我正在尝试使用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用于学习目的。请帮我解决这个问题。
答案 0 :(得分:2)
您的代码中的问题来自以下行:
nnModel.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
您必须将损失函数更改为categorical_crossentropy
,而不是binary_crossentropy
。实际上,在您的代码中,您必须编写nnModel.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
如果您有二进制分类问题,则可以选择以下两种变体之一:
Dense(1,activation='sigmoid')
+ loss = 'binary_crossentropy
'Dense(2,activation='softmax')
+ loss = 'categorical_crossentropy'
您可能还需要进行的唯一更改是对ImageDataGenerator
,将class_mode
(在第一种情况下,将其设置为'binary
',然后将其设置为'{{1} }”(在第二种情况下)