我有一组睁开和闭着眼睛的照片。
数据是通过这种方式从当前目录中使用keras收集的:
batch_size = 64
N_images = 84898 #total number of images
datagen = ImageDataGenerator(
rescale=1./255)
data_iterator = datagen.flow_from_directory(
'./Eyes',
shuffle = 'False',
color_mode='grayscale',
target_size=(h, w),
batch_size=batch_size,
class_mode = 'binary')
我有一个.csv文件,每只眼睛都有状态。
我已经建立了这个顺序模型:
num_filters = 8
filter_size = 3
pool_size = 2
model = Sequential([
Conv2D(num_filters, filter_size, input_shape=(90, 90, 1)),
MaxPooling2D(pool_size=pool_size),
Flatten(),
Dense(16, activation='relu'),
Dense(2, activation='sigmoid'), # Two classes. one for "open" and another one for "closed"
])
模型编制。
model.compile(
'adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
最后,我将所有数据与以下内容相结合:
model.fit(
train_images,
to_categorical(train_labels),
epochs=3,
validation_data=(test_images, to_categorical(test_labels)),
)
结果在50%左右波动,我不明白为什么。
发布于 2020-06-18 09:45:44
你现在的模型基本上只有一个卷积层。也就是说,定义和匹配num_filters
卷积滤波器(在本例中为3x3数组),以便当它们与图像卷积时,它们产生的特征在类之间尽可能具有区分性。然后执行You池,在传递到2个密集层之前稍微减少输出CNN功能的维数。
我首先要说的是,一个卷积层几乎肯定是不够的,特别是3x3过滤器。基本上,用一个卷积层,你能得到的最有意义的信息是边或线。对于函数逼近器(即完全连接的层)来说,这些特性仅比原始像素强度值更有用,因为它们在类内和类之间仍然具有极高的可变性。考虑一下,将一只眼睛2像素的图像向左移动会导致与你的一层CNN完全不同的输出值。您希望您的CNN输出是不变的规模,旋转,照明等。
在实践中,这意味着你需要更多的卷积层,相对简单的网至少有14个卷积层,而现代基于剩余层的网络通常有超过100个卷积层。尝试编写一个例程来定义顺序更复杂的网络,直到您开始看到性能的提高。
作为次要问题,通常您不希望在培训期间在最后一层输出中使用sigmoid()
激活函数。这会使渐变变平,并使你的损失更慢。实际上,您并不关心输出值介于0到1之间,您只关心它们的相对大小。通常的做法是使用交叉熵损失,它结合了loss函数(梯度比正常的softmax更稳定)和负的日志似然损失,就像您已经做过的那样。因此,由于log部分将输出值转换为所需的范围,因此不需要使用sigmoid激活函数。
https://stackoverflow.com/questions/62454130
复制相似问题