CNN模型在大多数情况下预测相同的值
Posted
技术标签:
【中文标题】CNN模型在大多数情况下预测相同的值【英文标题】:CNN model predict the same value in most part of cases 【发布时间】:2020-07-07 00:46:28 【问题描述】:我正在尝试训练一个用于图像分类的 CNN 模型。
有九个班级,每个班级有1000张图片。
这是我的代码
model = Sequential()
model.add(Conv2D(32, kernel_size=(5,5), activation='relu',kernel_initializer='random_uniform', input_shape=(128,646,1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())
model.add(Conv2D(16, kernel_size=(5,5), activation='relu', input_shape=(64,321,1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(16, activation = 'relu',kernel_initializer='normal'))
model.add(Dropout(0.5))
model.add(Dense(9, activation = 'softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
我已经在 MNIST 数据集上尝试过这个,它的工作将
但在我的数据集上,它总是预测相同的值。
(上方为真标签,下方为预测标签值)
[[0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0. 0.]]
[[0.11161657 0.11246169 0.11564494 0.11465651 0.11153363 0.10664304
0.11097018 0.11052497 0.10594855]
[0.11161657 0.11246169 0.11564494 0.11465651 0.11153363 0.10664304
0.11097018 0.11052497 0.10594855]
[0.11161657 0.11246169 0.11564494 0.11465651 0.11153363 0.10664304
0.11097018 0.11052497 0.10594855]
[0.11161657 0.11246169 0.11564494 0.11465651 0.11153363 0.10664304
0.11097018 0.11052497 0.10594855]
[0.11161657 0.11246169 0.11564494 0.11465651 0.11153363 0.10664304
0.11097018 0.11052497 0.10594855]]
Accuracy curves Loss curves
我已尝试更改 初始化器、优化器、损失函数、更多 epoch, ...仍然没有任何变化。
但是当我 1.将两个 Conv2D 内核数设置为 1 2.将第一个Conv2D激活函数设置为tanh
模型开始预测输入的不同值,但性能不会。
我主要是对感到困惑 1.将内核编号设置为 1 似乎并不常见,但根据我的经验,它会避免预测相同的值。 2.输入图像的值都大于零,但是设置activate函数为tanh也可以改变结果到不同的预测类?
另外,图片尺寸为128*646 每个图像值都在 0~80 范围内
array([[[33.74863434],
[27.84932709],
[22.6257019 ],
...,
[21.47132492],
[19.61938477],
[14.22393227]],
[[16.31633759],
[29.69265747],
[25.40621376],
...,
[28.50727081],
[11.46302605],
[ 4.04836655]],
[[ 9.1305275 ],
[10.00378227],
[28.46733665],
...,
[23.54629517],
[20.91897202],
[ 1.38314819]],
...,
[[63.33175659],
[66.34197998],
[68.40023804],
...,
[73.8707428 ],
[68.64536285],
[67.72910309]],
[[67.61167908],
[67.59188843],
[66.96526337],
...,
[70.63095856],
[74.70448303],
[72.90202332]],
[[71.49047852],
[74.54782104],
[69.39613342],
...,
[80. ],
[80. ],
[80. ]]])
更新
我的数据集来自免费音乐档案
包括轨道音频数据 (.mp3) 和轨道元数据(流派、艺术家、...)
我选择了小版本(8000音轨),通过libROSA包转换成谱图。
就像这个链接Using CNNs and RNNs for Music Genre Recognition
但我只想先尝试 CNN 模型。
libROSA包转换后的频谱图大小为128*646。
行数据是这样的
array([[-65.06227 , -47.759537, -44.17627 , ..., -39.40817 , -41.736862,
-25.19515 ],
[-65.40295 , -52.76098 , -49.17935 , ..., -16.40555 , -16.314035,
-17.56438 ],
[-69.481834, -56.676388, -50.506615, ..., -16.358843, -16.072405,
-18.807785],
...,
[-79.42308 , -59.743004, -36.382896, ..., -46.371193, -42.364635,
-50.037727],
[-80. , -63.419754, -41.73323 , ..., -50.383797, -46.90663 ,
-55.136078],
[-80. , -73.820724, -52.94601 , ..., -63.188026, -56.469948,
-60.473305]], dtype=float32)
我将该值除以 80 并计算这些频谱图的绝对值作为 CNN 模型输入
【问题讨论】:
问题不在于你的模型一直在预测同一个类,因为它根本没有学会区分类。看看预测[0.11161657 0.11246169 0.11564494 0.11465651 0.11153363 0.10664304 0.11097018 0.11052497 0.10594855]
。它为所有类别提供相同的概率!您的代码似乎没问题。有时这是非常简单的事情,例如您尚未对图像进行归一化,并且使用的学习率非常小(即优化器的默认值)。
这里似乎没有什么问题。你能包括你的预处理步骤吗?
谢谢你的建议,我的输入图像值都在0到80的范围内,我还需要对这些数据进行归一化吗?
已经添加了预处理部分,希望对您有所帮助。
您的问题现在解决了吗?否则,您能否分享完整的代码或 google colab 文件以重现您的问题,以便我们为您提供帮助。谢谢!
【参考方案1】:
为了社区的利益,在此处(回答部分)提及解决方案(即使它出现在评论部分)。同时添加更多建议。
将 Kernels
或 Filters
的数量增加到 50 以上,比如 64,提高了准确性。这是因为更多数量的Kernels/Filters
提高了Model
的表示能力,尤其是当数据不是很容易学习时。
为了改进Accuracy
,Model可以从
model = Sequential()
model.add(Conv2D(32, kernel_size=(5,5), activation='relu',kernel_initializer='random_uniform', input_shape=(128,646,1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())
model.add(Conv2D(16, kernel_size=(5,5), activation='relu', input_shape=(64,321,1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(16, activation = 'relu',kernel_initializer='normal'))
model.add(Dropout(0.5))
model.add(Dense(9, activation = 'softmax'))
到
model = Sequential()
model.add(Conv2D(64, kernel_size=(5,5),
activation='relu',kernel_initializer='random_uniform',
input_shape=(128,646,1))) # Increased the Number of Kernels in this Conv2D
Layer
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(5,5), activation='relu',
input_shape=(64,321,1))) # Increased the Number of Kernels in this Conv2D
Layer
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(256, activation = 'relu',
kernel_initializer='normal')) #Increased the Number of Neurons in this Dense
Layer
model.add(Dropout(0.5))
model.add(Dense(9, activation = 'softmax'))
另外,Input Data
位于0 to 80
范围内。将其规范化为0 and 1
之间的值将导致更好的accuracy
。
一般预处理步骤如下所示:
from tensorflow.keras.preprocessing import image
Test_Dir = 'Dogs_Vs_Cats_Small/test/cats'
Image_File = os.path.join(Test_Dir, 'cat.1545.jpg')
Image = image.load_img(Image_File, target_size = (128,646))
Image_Tensor = image.img_to_array(Image)
Image_Tensor = tf.expand_dims(Image_Tensor, axis = 0)
Image_Tensor = Image_Tensor/255.0
希望这会有所帮助。快乐学习!
【讨论】:
以上是关于CNN模型在大多数情况下预测相同的值的主要内容,如果未能解决你的问题,请参考以下文章