我正在使用下面的LeNet架构训练我的图像分类模型,我注意到这两个训练的val精度都没有提高。该领域的任何一位专家都可以解释可能出了什么问题吗?
训练样本-属于2类的110张图像。 验证-属于2类的50张图像。
#LeNet
import keras
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
#import dropout class if needed
from keras.layers import Dropout
from keras import regularizers
model = Sequential()
#Layer 1
#Conv Layer 1
model.add(Conv2D(filters = 6,
kernel_size = 5,
strides = 1,
activation = 'relu',
input_shape = (32,32,3)))
#Pooling layer 1
model.add(MaxPooling2D(pool_size = 2, strides = 2))
#Layer 2
#Conv Layer 2
model.add(Conv2D(filters = 16,
kernel_size = 5,
strides = 1,
activation = 'relu',
input_shape = (14,14,6)))
#Pooling Layer 2
model.add(MaxPooling2D(pool_size = 2, strides = 2))
#Flatten
model.add(Flatten())
#Layer 3
#Fully connected layer 1
model.add(Dense(units=128,activation='relu',kernel_initializer='uniform'
,kernel_regularizer=regularizers.l2(0.01)))
model.add(Dropout(rate=0.2))
#Layer 4
#Fully connected layer 2
model.add(Dense(units=64,activation='relu',kernel_initializer='uniform'
,kernel_regularizer=regularizers.l2(0.01)))
model.add(Dropout(rate=0.2))
#layer 5
#Fully connected layer 3
model.add(Dense(units=64,activation='relu',kernel_initializer='uniform'
,kernel_regularizer=regularizers.l2(0.01)))
model.add(Dropout(rate=0.2))
#layer 6
#Fully connected layer 4
model.add(Dense(units=64,activation='relu',kernel_initializer='uniform'
,kernel_regularizer=regularizers.l2(0.01)))
model.add(Dropout(rate=0.2))
#Layer 7
#Output Layer
model.add(Dense(units = 2, activation = 'softmax'))
model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
from keras.preprocessing.image import ImageDataGenerator
#Image Augmentation
train_datagen = ImageDataGenerator(
rescale=1./255, #rescaling pixel value bw 0 and 1
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
#Just Feature scaling
test_datagen = ImageDataGenerator(rescale=1./255)
training_set = train_datagen.flow_from_directory(
'/Dataset/Skin_cancer/training',
target_size=(32, 32),
batch_size=32,
class_mode='categorical')
test_set = test_datagen.flow_from_directory(
'/Dataset/Skin_cancer/testing',
target_size=(32, 32),
batch_size=32,
class_mode='categorical')
model.fit_generator(
training_set,
steps_per_epoch=50, #number of input (image)
epochs=25,
validation_data=test_set,
validation_steps=10) # number of training sample
Epoch 1/25
50/50 [==============================] - 52s 1s/step - loss: 0.8568 - accuracy: 0.4963 - val_loss: 0.7004 - val_accuracy: 0.5000
Epoch 2/25
50/50 [==============================] - 50s 1s/step - loss: 0.6940 - accuracy: 0.5000 - val_loss: 0.6932 - val_accuracy: 0.5000
Epoch 3/25
50/50 [==============================] - 48s 967ms/step - loss: 0.6932 - accuracy: 0.5065 - val_loss: 0.6932 - val_accuracy: 0.5000
Epoch 4/25
50/50 [==============================] - 50s 1s/step - loss: 0.6932 - accuracy: 0.4824 - val_loss: 0.6933 - val_accuracy: 0.5000
Epoch 5/25
50/50 [==============================] - 49s 974ms/step - loss: 0.6932 - accuracy: 0.4949 - val_loss: 0.6932 - val_accuracy: 0.5000
Epoch 6/25
50/50 [==============================] - 51s 1s/step - loss: 0.6932 - accuracy: 0.4854 - val_loss: 0.6931 - val_accuracy: 0.5000
Epoch 7/25
50/50 [==============================] - 49s 976ms/step - loss: 0.6931 - accuracy: 0.5015 - val_loss: 0.6918 - val_accuracy: 0.5000
Epoch 8/25
50/50 [==============================] - 51s 1s/step - loss: 0.6932 - accuracy: 0.4986 - val_loss: 0.6932 - val_accuracy: 0.5000
Epoch 9/25
50/50 [==============================] - 49s 973ms/step - loss: 0.6932 - accuracy: 0.5000 - val_loss: 0.6929 - val_accuracy: 0.5000
Epoch 10/25
50/50 [==============================] - 50s 1s/step - loss: 0.6931 - accuracy: 0.5044 - val_loss: 0.6932 - val_accuracy: 0.5000
Epoch 11/25
50/50 [==============================] - 49s 976ms/step - loss: 0.6931 - accuracy: 0.5022 - val_loss: 0.6932 - val_accuracy: 0.5000
Epoch 12/25
答案 0 :(得分:3)
从图层中删除所有 kernel_initializer='uniform'
个参数;不要在此处指定任何内容,强烈建议使用default初始化程序glorot_uniform
(而uniform
是特别糟糕的初始化程序)。
作为一般规则,请记住,为方便起见,有一些此类高级设置的默认值,建议隐式使用,除非您有特定的理由并且知道,否则最好不要搞乱它们。正是你在做什么。
特别是对于kernel_initializer
争论,我开始认为它给人们带来了很多不必要的痛苦(有关最新示例,请参见here)。
此外,默认情况下不应该使用辍学,尤其是在这种情况下,模型似乎很难学习任何东西。开始时没有任何缺失(注释掉各个图层),只有在看到过度拟合的迹象时才将其重新添加。
答案 1 :(得分:2)
最重要的是您正在使用loss = 'categorical_crossentropy'
,因为只有2个类,所以将其更改为loss = 'binary_crossentropy'
。并且还将class_mode='categorical'
中的class_mode='binary'
更改为flow_from_directory
。
正如@desertnaut正确提到的,categorical_crossentropy
与最后一层的softmax
激活紧密相关,如果将损失更改为binary_crossentropy
,则最后一个激活也应更改为sigmoid
。
其他改进:
horizontal_flip
,vertical_flip
,shear_range
,ImageDataGenerator的zoom_range)来增加训练和验证图像的数量。按照@desertnaut的建议移动评论以回答问题-
问题-谢谢!是的,我想的是更少的数据。再加一个 问题-为什么添加比conv层更密集的层 对模型有负面影响,当我们 决定我们要使用多少个conv和致密层? – 2天前Arun_Ramji_Shanmugam
答案-为回答问题的第一部分,Conv2D层保留了 图像的空间信息和要学习的权重取决于 层中提到的内核大小和步幅,如密集 层需要将Conv2D的输出展平并进一步使用 因此会丢失空间信息。同样致密的层增加了更多 权重数量,例如2个512的密集层相加 (512 * 512)= 262144模型的参数或权重(必须由 该模型)。这意味着您需要训练更多的纪元, 具有良好的炒作参数设置以学习这些权重。 – Tensorflow Warriors 2天前
答案-要回答问题的第二部分,请使用系统的实验 找出最适合您的特定数据集的方法。还取决于 您拥有的处理能力。请记住,更深层次的网络永远 更好,但需要更多数据并增加学习的复杂性。 常规方法是寻找类似的问题并深入研究 学习架构已经被证明是可行的。还有我们 可以灵活地使用预训练的模型,例如resnet,vgg 等等,通过冻结层的一部分并进行训练来使用这些模型 在其余层上。 – 2天前的Tensorflow Warriors
问题-谢谢您的详细回答!如果您不打扰另一个问题 -因此,当我们使用已经训练好的模型(可能是一些层)时,是否需要在与我们要输入的模型相同的输入数据上进行训练 工作? –昨天Arun_Ramji_Shanmugam
答案-传递学习用于图像分类的直觉是 如果模型是在足够大和足够通用的数据集上训练的,则这 模型将有效地充当视觉世界的通用模型。 您可以在此处找到带有说明的转学示例- tensorflow.org/tutorials/images/transfer_learning。 – Tensorflow 昨天的勇士们