keras图像分类器模型配置

时间:2020-02-16 04:38:29

标签: python tensorflow machine-learning keras deep-learning

我正在尝试使用Keras和TensorFlow学习图像分类。 我指的是https://www.kaggle.com/c/dogs-vs-cats问题。

我的代码如下:

#!/usr/bin/env python
# coding: utf-8

# # Cats and Dogs Identification Kaggle
# 
# https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html

# ## Tensorflow and GPU Memory Config

# In[14]:


import tensorflow as tf
from tensorflow.keras.models import Sequential
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img

from tensorflow.keras.layers import Dense, Flatten, Activation, Conv2D, MaxPooling2D,  Reshape, BatchNormalization
from keras import backend as K 


# tf.reset_default_graph()
# tf.set_random_seed(42)
# tf.config.set_per_process_memory_growth(True)
# tf.config.gpu.set_per_process_memory_fraction(0.4)
tf.debugging.set_log_device_placement(True)

print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))
tf.config.experimental.list_physical_devices('GPU')

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  # Restrict TensorFlow to only allocate 1GB of memory on the first GPU
  try:
    tf.config.experimental.set_virtual_device_configuration(
        gpus[0],
        [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=2048)])
    logical_gpus = tf.config.experimental.list_logical_devices('GPU')
    print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
  except RuntimeError as e:
    # Virtual devices must be set before GPUs have been initialized
    print(e)

print('Keras image_data_format {}'.format(K.image_data_format()))    
print('if keras image_data_format is channel_last means data should be loaded in 32X32X3 dimensions')


# In[2]:


import os
import shutil
from shutil import copyfile
from random import seed
from random import random

def createPathIfNoExists(path):
    if not os.path.exists(path):
        os.mkdir(path)


cats_dir = '/cats'
dogs_dir = '/dogs'

source_images = '/home/user/Desktop/dogs_cat_keras'
data_dir = source_images + '/data'

train_dir = data_dir + '/train'
train_cats_dir = train_dir + cats_dir
train_dogs_dir = train_dir + dogs_dir

validation_dir = data_dir + '/validation'
validation_cats_dir = validation_dir + cats_dir
validation_dogs_dir = validation_dir + dogs_dir




createPathIfNoExists(data_dir)

createPathIfNoExists(train_dir)
createPathIfNoExists(train_cats_dir)
createPathIfNoExists(train_dogs_dir)

createPathIfNoExists(validation_dir)
createPathIfNoExists(validation_cats_dir)
createPathIfNoExists(validation_dogs_dir)

print('Source directory {}'.format(source_images))
print('Data directory {}'.format(data_dir))
print('train directory {}'.format(train_dir))
print('train cats directory {}'.format(train_cats_dir))
print('train dogs directory {}'.format(train_dogs_dir))
print('validation directory {}'.format(validation_dir))
print('validation directory {}'.format(validation_cats_dir))
print('validation directory {}'.format(validation_dogs_dir))



# inputFiles = source_images + '/train'

# cats = [inputFiles+'/' + d for d in os.listdir(inputFiles) if d.startswith('cat')]

# print('All cats count {}'.format(len(cats)))

# dogs = [inputFiles+'/' + d for d in os.listdir(inputFiles) if d.startswith('dog')]

# print('All dogs count {}'.format(len(dogs)))

# data_split_70 = 8400 

# train_cats = cats[:data_split_70]
# validation_cats = cats[data_split_70:]


# train_dogs = dogs[:data_split_70]
# validation_dogs = dogs[data_split_70:]

# print('Total train cats {} and validation cats {}'.format(len(train_cats), len(validation_cats)))
# print('Total train dogs {} and validation dogs {}'.format(len(train_dogs), len(validation_dogs)))

# # Put train cats data in train directory
# for item in train_cats: 
#     if os.path.isfile(item):
#         shutil.copyfile(item, train_cats_dir + '/' + os.path.basename(item))

# # Put validation cats data in validation directory
# for item in validation_cats:
#     if os.path.isfile(item):
#         shutil.copyfile(item, validation_cats_dir + '/' + os.path.basename(item))

# # Put train cats data in train directory
# for item in train_dogs:
#     if os.path.isfile(item):
#         shutil.copyfile(item, train_dogs_dir + '/' + os.path.basename(item))

# # Put validation cats data in validation directory
# for item in validation_dogs:
#     if os.path.isfile(item):
#         shutil.copyfile(item, validation_dogs_dir + '/' + os.path.basename(item))    


# ## General imports

# In[15]:


import datetime
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.model_selection import KFold, GridSearchCV, RandomizedSearchCV
from sklearn.preprocessing import MinMaxScaler

get_ipython().run_line_magic('matplotlib', 'inline')
import matplotlib.pyplot as plt

from sklearn.neighbors import KNeighborsClassifier

import h5py


# ## Data Import

# In[16]:


dataGenerator = ImageDataGenerator(rotation_range=40,
                                  width_shift_range=0.2,
                                  height_shift_range=0.2,
                                  shear_range=0.2,
                                  zoom_range=0.2,
                                  horizontal_flip=True,
                                  fill_mode='nearest')


# ### Image Display

# In[17]:


img = load_img('/home/user/Desktop/dogs_cat_keras/data/train/cats/cat.12467.jpg')  # this is a PIL image
x = img_to_array(img)  # this is a Numpy array with shape (width X height X 3)
print(x.shape)
# print(type(img))
# print(img.size)
# print(img.mode)
plt.imshow(x/255)
plt.show()
print('Shape before reshape {}'.format(x.shape))

## Generate data = 0
x = x.reshape((1,) + x.shape)  # this is a Numpy array with shape (1, width, height, 3)
print('Shape after reshape {}'.format(x.shape))


# ### Generate augumented data using image generator

# In[6]:


# import os

# augumented_data_path = data_path + '/preview'

# if not os.path.exists(augumented_data_path):
#     os.mkdir(augumented_data_path)

# i = 0
# for batch in dataGenerator.flow(x, batch_size=1,
#                           save_to_dir=augumented_data_path, save_prefix='cat', save_format='jpeg'):
#     i += 1
#     if i > 20:
#         break  # otherwise the generator would loop indefinitely


# ### Building Graph 

# In[23]:


img_width, img_height = 150, 150
input_shape = (img_width, img_height, 3) 

nnModel = Sequential()

nnModel.add(Flatten(input_shape=(input_shape)))
nnModel.add(Dense(32, activation='relu'))
nnModel.add(Dense(16, activation='relu'))
nnModel.add(Dense(2, activation='softmax'))


# ### Compile function

# In[26]:


nnModel.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])


# ### Train Generator

# In[20]:


batch_size = 32

train_data_gen = ImageDataGenerator(rescale = 1/255,
                                    shear_range=0.2,
                                    zoom_range=0.2,
                                    horizontal_flip=True)
train_generator = train_data_gen.flow_from_directory(
        train_dir,  # this is the target directory
        target_size=(img_width, img_height),  # all images will be resized to 150x150
        batch_size=batch_size,
        class_mode='binary')

print('Train path {}'.format(train_dir))

test_data_gen = ImageDataGenerator(rescale = 1/255)

print('Test path {}'.format(validation_dir))

validation_generator = test_data_gen.flow_from_directory(
        validation_dir,  # this is the target directory
        target_size=(img_width, img_height),  # all images will be resized to 150x150
        batch_size=batch_size,
        class_mode='binary')


# In[24]:


nnModel.summary()


# ### Train

# In[27]:



nnModel.fit_generator(train_generator, 
                      steps_per_epoch=2048, 
                      epochs=64, 
                      validation_data=validation_generator, 
                      validation_steps=1024)

我正在追随异常

<ipython-input-27-59bf3c75cdc4> in <module>
      3                       epochs=64,
      4                       validation_data=validation_generator,
----> 5                       validation_steps=1024)...

A target array with shape (32, 1) was passed for an output of shape (None, 2) while using as loss `binary_crossentropy`. This loss expects targets to have the same shape as the output.

问题陈述有很多笔记本解决方案,但是在这里我不想将cnn用于学习目的。请帮我解决这个问题。

1 个答案:

答案 0 :(得分:2)

您的代码中的问题来自以下行:

nnModel.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])

您必须将损失函数更改为categorical_crossentropy,而不是binary_crossentropy。实际上,在您的代码中,您必须编写nnModel.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])

如果您有二进制分类问题,则可以选择以下两种变体之一:

  1. Dense(1,activation='sigmoid') + loss = 'binary_crossentropy'
  2. Dense(2,activation='softmax') + loss = 'categorical_crossentropy'

您可能还需要进行的唯一更改是对ImageDataGenerator,将class_mode(在第一种情况下,将其设置为'binary',然后将其设置为'{{1} }”(在第二种情况下)