在以下用于分类的ResNet50模型中,验证准确性为0的原因

时间:2019-12-28 11:06:38

标签: python-3.x tensorflow machine-learning keras deep-learning

我已经写了这个code,以使用Resnet50对猫和狗进行分类。实际上,在学习过程中,我得出的结论是,转移学习为深度学习模型提供了非常好的准确性,但是我最终得到的结果要差得多,而且我不明白其原因。任何带有推理的描述将非常有帮助。该数据集包含2000张猫狗图像作为训练,并包含1000张图像作为验证集。

以下总结了我的模型

from tensorflow.keras.applications import ResNet50
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, InputLayer, Flatten, GlobalAveragePooling2D
num_classes = 2
IMG_SIZE = 224
IMG_SHAPE = (IMG_SIZE, IMG_SIZE, 3)
my_new_model=tf.keras.applications.ResNet50(include_top=False, weights='imagenet', input_shape=IMG_SHAPE, pooling='avg', classes=2)
my_new_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])


from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications.resnet50 import preprocess_input
train_datagen = ImageDataGenerator(
 preprocessing_function=preprocess_input,
 rotation_range=40,
 width_shift_range=0.2,
 height_shift_range=0.2,
 shear_range=0.2,
 zoom_range=0.2,
 horizontal_flip=True,)

# Note that the validation data should not be augmented!
test_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)

train_generator = train_datagen.flow_from_directory(
     train_dir,  # This is the source directory for training images
     target_size=(224,224),  # All images will be resized to 224x224
     batch_size=20,
     class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
     validation_dir,
     target_size=(224, 224),
     class_mode='binary')

my_new_model.fit_generator(
     train_generator,
     epochs = 8,
     steps_per_epoch=100,
     validation_data=validation_generator)

为此,我获得了培训日志,

Train for 100 steps, validate for 32 steps
Epoch 1/8
100/100 - 49s - loss: 7889.4051 - accuracy: 0.0000e+00 - val_loss: 7834.5318 - val_accuracy: 0.0000e+00
Epoch 2/8
100/100 - 35s - loss: 7809.7583 - accuracy: 0.0000e+00 - val_loss: 7775.1556 - val_accuracy: 0.0000e+00
Epoch 3/8
100/100 - 35s - loss: 7808.4858 - accuracy: 0.0000e+00 - val_loss: 7765.3964 - val_accuracy: 0.0000e+00
Epoch 4/8
100/100 - 35s - loss: 7808.0520 - accuracy: 0.0000e+00 - val_loss: 7764.0735 - val_accuracy: 0.0000e+00
Epoch 5/8
100/100 - 35s - loss: 7807.7891 - accuracy: 0.0000e+00 - val_loss: 7762.4891 - val_accuracy: 0.0000e+00
Epoch 6/8
100/100 - 35s - loss: 7807.6872 - accuracy: 0.0000e+00 - val_loss: 7762.1766 - val_accuracy: 0.0000e+00
Epoch 7/8
100/100 - 35s - loss: 7807.6633 - accuracy: 0.0000e+00 - val_loss: 7761.9766 - val_accuracy: 0.0000e+00
Epoch 8/8
100/100 - 35s - loss: 7807.6514 - accuracy: 0.0000e+00 - val_loss: 7761.9346 - val_accuracy: 0.0000e+00
<tensorflow.python.keras.callbacks.History at 0x7f5adff722b0>

1 个答案:

答案 0 :(得分:0)

当我复制模型时,在resnet(即Base_net)和致密层之间添加了扁平层,如下所示:

Base_net = ResNet50(include_top = False, weights = 'imagenet', input_shape = input_shape)

model = Sequential()
model.add(Base_net)
model.add(Flatten())
model.add(Dense(units = num_classes, activation = 'softmax'))
model.summary()

model.compile(loss = 'categorical_crossentropy',
            optimizer = 'Adam',
            metrics = ['accuracy'])

输出:

Layer (type)                 Output Shape              Param #   
=================================================================
resnet50 (Model)             (None, 7, 7, 2048)        23587712  
_________________________________________________________________
flatten_5 (Flatten)          (None, 100352)            0         
_________________________________________________________________
dense_9 (Dense)              (None, 1)                 100353    
=================================================================
Total params: 23,688,065
Trainable params: 23,634,945
Non-trainable params: 53,120
_________________________________________________________________
Epoch 1/3
100/100 [==============================] - 84s 837ms/step - loss: 0.0000e+00 - accuracy: 0.5085 - val_loss: 0.0000e+00 - val_accuracy: 0.5000
Epoch 2/3
100/100 [==============================] - 81s 806ms/step - loss: 0.0000e+00 - accuracy: 0.4953 - val_loss: 0.0000e+00 - val_accuracy: 0.5050
Epoch 3/3
100/100 [==============================] - 80s 801ms/step - loss: 0.0000e+00 - accuracy: 0.4965 - val_loss: 0.0000e+00 - val_accuracy: 0.5080

要解决您的问题,必须将损失函数更改为binary_crossentropy,并在最后一个密集层中将激活函数替换为sigmoid,从而解决了您的问题。为了获得更好的精度值,请实施超参数调整。

注意:我们通常会看到批处理大小为2的幂,这是因为优化的矩阵运算库的有效工作

请参考下面的工作代码,其中准确性

%tensorflow_version 2.x

import tensorflow as tf
from tensorflow.keras.applications import ResNet50
import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Sequential

from google.colab import drive
drive.mount('/content/drive')

train_dir  = '/content/drive/My Drive/Dogs_Vs_Cats/train'
test_dir = '/content/drive/My Drive/Dogs_Vs_Cats/test'

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

#train_samples = 2000
#test_samples = 1000
epochs = 8
batch_size = 32

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

test_datagen = ImageDataGenerator(
    rescale = 1. /255)

train_data = train_datagen.flow_from_directory(
    train_dir,
    target_size = (img_width, img_height),
    batch_size = batch_size,
    class_mode = 'binary')

test_data = test_datagen.flow_from_directory(
    test_dir,
    target_size = (img_width, img_height),
    #batch_size = batch_size,
    class_mode = 'binary')



# The Convolutional Base of the Pre-Trained Model will be added as a Layer in this Model

Conv_Base = ResNet50(include_top = False, weights = 'imagenet', input_shape = input_shape)

model = Sequential()
model.add(Conv_Base)
model.add(Flatten())
model.add(Dense(units = 256, activation = 'relu'))
model.add(Dropout(0.5))
model.add(Dense(units = 1, activation = 'sigmoid'))
model.summary()

model.compile(loss = 'binary_crossentropy',
            optimizer = 'Adam',
            metrics = ['accuracy'])

model.fit_generator(
        train_data,
        steps_per_epoch = 100,
        epochs = 8,
        validation_data = test_data,
        verbose = 1,
        validation_steps = 32)

输出:

Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.

Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
resnet50 (Model)             (None, 7, 7, 2048)        23587712  
_________________________________________________________________
flatten_4 (Flatten)          (None, 100352)            0         
_________________________________________________________________
dense_8 (Dense)              (None, 256)               25690368  
_________________________________________________________________
dropout_4 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_9 (Dense)              (None, 1)                 257       
=================================================================
Total params: 49,278,337
Trainable params: 49,225,217
Non-trainable params: 53,120
_________________________________________________________________
Epoch 1/8
100/100 [==============================] - 1828s 18s/step - loss: 1.9865 - accuracy: 0.6401 - val_loss: 0.7398 - val_accuracy: 0.5000
Epoch 2/8
100/100 [==============================] - 65s 646ms/step - loss: 0.6642 - accuracy: 0.6951 - val_loss: 0.7094 - val_accuracy: 0.5000
Epoch 3/8
100/100 [==============================] - 65s 652ms/step - loss: 0.5662 - accuracy: 0.7673 - val_loss: 0.7088 - val_accuracy: 0.4950
Epoch 4/8
100/100 [==============================] - 65s 647ms/step - loss: 0.4362 - accuracy: 0.8330 - val_loss: 0.7026 - val_accuracy: 0.4950
Epoch 5/8
100/100 [==============================] - 65s 649ms/step - loss: 0.3998 - accuracy: 0.8405 - val_loss: 0.8281 - val_accuracy: 0.5070
Epoch 6/8
100/100 [==============================] - 65s 647ms/step - loss: 0.5733 - accuracy: 0.7986 - val_loss: 0.8699 - val_accuracy: 0.4970
Epoch 7/8
100/100 [==============================] - 65s 647ms/step - loss: 0.6359 - accuracy: 0.7860 - val_loss: 0.7071 - val_accuracy: 0.5020
Epoch 8/8
100/100 [==============================] - 65s 653ms/step - loss: 0.5514 - accuracy: 0.7673 - val_loss: 0.6590 - val_accuracy: 0.5910