CNN-如何使用keras正确获取val_loss和val_acc?

时间:2019-02-27 20:48:54

标签: python-3.x machine-learning keras deep-learning conv-neural-network

显微镜图像为.tif格式,并具有以下规格:

  • 颜色模型:R(ed)G(reen)B(lue)
  • 尺寸:2048 x 1536像素
  • 像素刻度:0.42μmx 0.42μm
  • 内存空间:10-20 MB(大约)
  • 标签类型:按图像显示
  • 4类:良性,侵入性,原位,正常

CNN kodu:

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


classifier = Sequential()


classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Flatten())


classifier.add(Dense(activation = 'relu', units = 128))
classifier.add(Dense(activation = 'softmax', units = 4))


classifier.compile(optimizer = 'adam', loss = 'sparse_categorical_crossentropy', metrics = ['accuracy'])


from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale = 1./255,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = True)

test_datagen = ImageDataGenerator(rescale = 1./255,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = True)

training_set = train_datagen.flow_from_directory('BioImaging2015/breasthistology/Training_data',
                                                 target_size = (64, 64),
                                                 batch_size = 1,
                                                 class_mode = 'binary')

test_set = test_datagen.flow_from_directory('BioImaging2015/breasthistology/Test_data',
                                            target_size = (64, 64),
                                            batch_size = 1,
                                            class_mode = 'binary')

classifier.fit_generator(training_set,
                         samples_per_epoch = 5000,
                         nb_epoch = 20,
                         validation_data = test_set,
                         nb_val_samples = len(test_set))

数据:

Found 249 images belonging to 4 classes.
Found 36 images belonging to 4 classes.

起初,test_data位于单个文件中。但他犯了一个错误

Found 0 images belonging to 0 classes.

然后我将它分成4个文件。

输出:

Epoch 1/20
5000/5000 [==============================] - 1056s 211ms/step - loss: 1.3914 - acc: 0.2754 - val_loss: 1.3890 - val_acc: 0.2500
Epoch 2/20
5000/5000 [==============================] - 1056s 211ms/step - loss: 1.2874 - acc: 0.3740 - val_loss: 1.6325 - val_acc: 0.3333
Epoch 3/20
5000/5000 [==============================] - 1056s 211ms/step - loss: 0.7412 - acc: 0.7098 - val_loss: 1.4916 - val_acc: 0.4722
Epoch 4/20
5000/5000 [==============================] - 1056s 211ms/step - loss: 0.3380 - acc: 0.8780 - val_loss: 1.4263 - val_acc: 0.5278
Epoch 5/20
5000/5000 [==============================] - 1057s 211ms/step - loss: 0.1912 - acc: 0.9346 - val_loss: 2.1176 - val_acc: 0.4722
Epoch 6/20
5000/5000 [==============================] - 1103s 221ms/step - loss: 0.1296 - acc: 0.9568 - val_loss: 2.8661 - val_acc: 0.4167
Epoch 7/20
5000/5000 [==============================] - 1182s 236ms/step - loss: 0.0964 - acc: 0.9698 - val_loss: 3.5154 - val_acc: 0.3611
Epoch 8/20
5000/5000 [==============================] - 1245s 249ms/step - loss: 0.0757 - acc: 0.9790 - val_loss: 3.6839 - val_acc: 0.3889
Epoch 9/20
3540/5000 [====================>.........] - ETA: 5:54 - loss: 0.0664 - acc: 0.9819

这是我的理解:

  1. 损失在减少,acc在增加。因此,这表明建模训练得很好。

我的问题是:

  1. val_acc在减少,而val_loss在增加。为什么?这太合身了吗?如果我写辍学,acc和val_acc不会增加。两个损失并没有减少。
  2. 9次练习后,acc仍在增加。所以我应该多使用 当acc停止增加时会停止并停止吗?不然我该停在哪里 val_acc停止增加?但是val_acc不会增加。
  3. cnn网络正确吗?我看不出问题出在哪里。

更改:

  1. loss = 'sparse_categorical_crossentropy' -> loss = 'categorical_crossentropy'
  2. class_mode = 'binary' -> class_mode = 'categorical'

output2:

Epoch 1/20
5000/5000 [==============================] - 1009s 202ms/step - loss: 1.3878 - acc: 0.2752 - val_loss: 1.3893 - val_acc: 0.2500
Epoch 2/20
5000/5000 [==============================] - 1089s 218ms/step - loss: 1.3844 - acc: 0.2774 - val_loss: 1.3895 - val_acc: 0.2500
Epoch 3/20
5000/5000 [==============================] - 1045s 209ms/step - loss: 1.3847 - acc: 0.2764 - val_loss: 1.3894 - val_acc: 0.2500
Epoch 4/20
5000/5000 [==============================] - 1077s 215ms/step - loss: 1.3843 - acc: 0.2764 - val_loss: 1.3885 - val_acc: 0.2500
Epoch 5/20
5000/5000 [==============================] - 1051s 210ms/step - loss: 1.3841 - acc: 0.2768 - val_loss: 1.3887 - val_acc: 0.2500
Epoch 6/20
5000/5000 [==============================] - 1050s 210ms/step - loss: 1.3841 - acc: 0.2782 - val_loss: 1.3891 - val_acc: 0.2500
Epoch 7/20
5000/5000 [==============================] - 1053s 211ms/step - loss: 1.3836 - acc: 0.2780 - val_loss: 1.3900 - val_acc: 0.2500

1 个答案:

答案 0 :(得分:0)

由于您在最后一层具有四个类并激活了softmax,因此对我来说,您极不可能选择class_mode='binary'的{​​{1}}和flow_from_directory()的{​​{1}}正确。用这种方式生成的标签没有意​​义。

loss='sparse_categorical_crossentropy'将生成格式为classifier.compile()的标签,该标签仅对是/否预测有意义(因此为“二进制”),而class_mode='binary'则期望格式为{{1 }}(每个类一个整数)。

请尝试使用[0,1,1,0,1,1,...]loss='sparse_categorical_crossentropy'。 这将生成一个热编码的标签,例如

[1,3,2,4,3,2,1,2,...]

这正是class_mode='categorical'期望得到的。同样,在最后一层中选择loss='categorical_crossentropy'也非常适合此操作,因为这可以确保最后一层中的四个值总和等于[[0,0,1,0], [0,1,0,0], [0,0,0,1], ... ]

关于您的问题:

  1. 是的,由于标签不正确(它们没有意义),您很有可能面临过度拟合的问题。您的模型基本上是在学习随机标签(训练数据),因此在其他随机标签(验证数据)上效果不佳。
  2. loss='categorical_crossentropy'停止增加时,您应该停止。是的,在您的情况下,在两个时代之后已经达到了这一点。但是对于好的模型,这是一种常见的做法。您的理解存在一个缺陷:在训练数据上表现出色并不是目标!记住,最后,您希望模型预测以前从未见过的图片,因此只有验证数据可以告诉您事实。 (实际上,最好有一个在训练过程中从未被触及过的测试数据集,并在调用activation='softmax'1之后最后对那个数据集进行评估。
  3. 实际网络是正确的,只是您的数据不正确(如上所述)。但是,如果在我建议的修复之后它仍然不能正常工作,则您将需要在卷积层中尝试使用更多数量的要素,并添加更多的卷积层。中间层以0.2到0.5的比率丢失后,始终是避免过度拟合的好方法。您将需要尝试这些设置。