Sun*_*gke 6 python machine-learning neural-network deep-learning keras
这是我的代码.我想使用Keras进行多分类.训练时vcl_acc更好,但预测值总是相同的值.我很困惑,请帮助我
train.py
# coding: UTF-8
# author: Sun Yongke (sunyongke@gmail.com)
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import EarlyStopping
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.optimizers import SGD
# Dense(64) is a fully-connected layer with 64 hidden units.
# in the first layer, you must specify the expected input data shape:
# here, 20-dimensional vectors.
# dimensions of our images.
img_width, img_height = 300, 300
nb_epoch=20
train_data_dir = '../picture/samples_300_2/train'
validation_data_dir = '../picture/samples_300_2/validation'
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=40000,
color_mode='grayscale',
save_format="jpg",
save_to_dir="after/train",
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=500,
color_mode='grayscale',
save_format="jpg",
save_to_dir="after/test",
class_mode='categorical')
model = Sequential()
# input: 100x100 images with 3 channels -> (3, 100, 100) tensors.
# this applies 32 convolution filters of size 3x3 each.
model.add(Convolution2D(32, 3, 3, border_mode='valid', input_shape=(img_width, img_height,1)))
model.add(Activation('relu'))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Convolution2D(64, 3, 3, border_mode='valid'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
# Note: Keras does automatic shape inference.
model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(14))
model.add(Activation('softmax'))
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)
nb_train_samples=len(train_generator.filenames)
nb_validation_samples=len(validation_generator.filenames)
early_stopping = EarlyStopping(monitor='val_loss', patience=2)
model.fit_generator(
train_generator,
samples_per_epoch=nb_train_samples,
nb_epoch=nb_epoch,
validation_data=validation_generator,
nb_val_samples=nb_validation_samples, callbacks=[early_stopping])
#save model
model.save("sykm.2.h5")
Run Code Online (Sandbox Code Playgroud)
培训产出如下
Epoch 2/50
3005/3005 [==============================] - 270s - loss: 0.2227 - acc: 0.9294 - val_loss: 0.1985 - val_acc: 0.9316
Epoch 3/50
3005/3005 [==============================] - 269s - loss: 0.2105 - acc: 0.9310 - val_loss: 0.1858 - val_acc: 0.9338
Epoch 4/50
3005/3005 [==============================] - 271s - loss: 0.1964 - acc: 0.9333 - val_loss: 0.3572 - val_acc: 0.9160
Epoch 5/50
3005/3005 [==============================] - 268s - loss: 0.1881 - acc: 0.9349 - val_loss: 0.1513 - val_acc: 0.9413
Epoch 6/50
3005/3005 [==============================] - 268s - loss: 0.1935 - acc: 0.9342 - val_loss: 0.1581 - val_acc: 0.936
Run Code Online (Sandbox Code Playgroud)
predict.py
# coding: UTF-8
# author: Sun Yongke (sunyongke@gmail.com)
from keras.models import load_model
model = load_model('sykm.2.h5')
img_width, img_height = 300, 300
from keras.preprocessing.image import ImageDataGenerator
test_datagen = ImageDataGenerator(rescale=1./255)
validation_data_dir = 'samples_300/validation'
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=32,
class_mode='categorical')
nb_validation_samples=len(validation_generator.filenames)
out=model.predict_generator(validation_generator,nb_validation_samples)
print "out"
print out
Run Code Online (Sandbox Code Playgroud)
输出总是相同的,即使我使用不同的图片测试如下
Using TensorFlow backend.
Found 60 images belonging to 2 classes.
out
[[ 0.06170857 0.06522226 0.06400252 0.08250671 0.07548683 0.07643672
0.07131153 0.07487586 0.07607967 0.04719007 0.07641899 0.08824327
0.05421595 0.08630092]
[ 0.06170857 0.06522226 0.06400252 0.08250671 0.07548683 0.07643672
0.07131153 0.07487586 0.07607967 0.04719007 0.07641899 0.08824327
0.05421595 0.08630092]
....]
Run Code Online (Sandbox Code Playgroud)
好吧,在寻找解决方案的 1 个月后,我尝试了一切:降低学习率,更改优化器,使用更大的数据集,增加和减少模型复杂性,将输入形状更改为越来越小的图像,将导入从from keras import更改为from tensorflow.keras import和更进一步from tensorflow.python.keras import,改变每一层的激活函数,组合它们,尝试其他数据集等......没有任何帮助。即使我使用像 VGG16/19 这样的网络,我的结果也是一样的。但是,昨天,我正在阅读一本书(使用 Keras 进行深度学习 - Antonio Gulli,Sujit Pal),我意识到汽车人使用这样的导入:
from keras.layers.core import Dense, Flatten, Dropout
Run Code Online (Sandbox Code Playgroud)
而不是这样:
from keras.layers import Dense, Flatten, Dropout
Run Code Online (Sandbox Code Playgroud)
Conv 也是如此,我使用的是:
from keras.layers import Conv2D, MaxPooling2D, SeparableConv2D
Run Code Online (Sandbox Code Playgroud)
和汽车人使用:
from keras.layers.convolutional import Conv2D, MaxPooling2D, SeparableConv2D
Run Code Online (Sandbox Code Playgroud)
当我更改导入时,一切终于开始工作了!我不知道这是一个错误还是类似的东西,因为现在我的模型即使在预测同一类的数据集中也总是有效。所以现在我正在使用这样的导入,例如:
from keras.layers.core import Dense, Dropout, Flatten
from keras.layers.convolutional import Conv2D, MaxPooling2D, SeparableConv2D
Run Code Online (Sandbox Code Playgroud)
试试这个,如果不起作用,看看你的数据集是否平衡,例如,如果你的问题是对猫和狗的图像进行分类,并且你有 200 张猫图像和 800 张狗图像,请尝试使用一些不那么不同的图像因为它可能会导致问题:如果我说 10/10 图像是狗,你的模型可以“思考”好,所以我得到 80% 的准确率,但这不是我们想要的。您可以使用class_weight,如果你没有更多的图片来平衡你的数据集,一切都会好的,你可以如用数据增强。你也可以使用回调,比如ReduceLROnPlateau当你的损失没有降低时降低你的学习率。您可以增加您的batch_size,不要忘记对您的数据进行洗牌ImageDataGenerator并标准化您的图像,如下所示:
g2 = ImageDataGenerator(rescale=1./255)
Run Code Online (Sandbox Code Playgroud)
所有这些事情都非常重要,但没有什么能真正帮助我。唯一有效的是导入keras.layers.core和keras.layers.convolutional,这也可以帮助您!
您的问题似乎是由数据集中的巨大类不平衡引起的.可以看出,0为每个示例分配一个类可以提供超过90%的准确性.为了解决这个问题,您可以使用以下策略:
重新平衡数据集:通过对较不频繁的类进行上采样或对较频繁的类进行下采样.
调整班级权重:通过为较不频繁的班级设置较高的班级权重,您将推广您的网络培训,以便更多地关注下采样班级.
| 归档时间: |
|
| 查看次数: |
4835 次 |
| 最近记录: |