【问题标题】:Deep CNN doesn't learn and accuracy just stay in same value深度 CNN 不学习,准确率保持不变
【发布时间】:2020-06-21 19:11:22
【问题描述】:

我有一个基于 ResNet 的 Deep CNN,以及一个用于对数字进行分类的数据集 (10000, 50,50,1)。当我运行它开始学习时,准确度会停止在某个值并轻轻摆动(大约 0.2)。我想知道它是否过度拟合或涉及其他问题?

这是身份块:

def identity_block(X, f, filters, stage, block):
# defining name basics
conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch'

# retrieve filters
F1, F2, F3 = filters

# save the shortcut
X_shortcut = X

# first component
X = Conv2D(filters=F1, kernel_size=(1, 1), strides=(1, 1), padding='valid', name=conv_name_base + '2a',
           kernel_initializer=initializers.glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2a')(X)
X = Activation('relu')(X)

# second component
X = Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding='same', name=conv_name_base + '2b',
           kernel_initializer=initializers.glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2b')(X)
X = Activation('relu')(X)

# third component
X = Conv2D(filters=F3, kernel_size=(1, 1), strides=(1, 1), padding='valid', name=conv_name_base + '2c',
           kernel_initializer=initializers.glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2c')(X)


# final component
X = Add()([X, X_shortcut])
X = Activation('relu')(X)

return X

和卷积块:

def conv_block(X, f, filters, stage, block, s=2):
conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch'

# Retivr filters
F1, F2, F3 = filters

# Save shortcut
X_shortcut = X

# First component
X = Conv2D(F1, kernel_size=(1, 1), strides=(s, s), name=conv_name_base + '2a',
           kernel_initializer=initializers.glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2a')(X)
X = Activation('relu')(X)

# Second component
X = Conv2D(F2, kernel_size=(f, f), strides=(1, 1), padding='same', name=conv_name_base + '2b',
           kernel_initializer=initializers.glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2b')(X)
X = Activation('relu')(X)

# third component
X = Conv2D(F3, kernel_size=(1, 1), strides=(1, 1), name=conv_name_base + '2c', padding='valid',
           kernel_initializer=initializers.glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2c')(X)

# short cut
X_shortcut = Conv2D(F3, kernel_size=(1, 1), strides=(s, s), name=conv_name_base + '1',
                    kernel_initializer=initializers.glorot_uniform(seed=0))(X_shortcut)
X_shortcut = BatchNormalization(axis=3, name=bn_name_base + '1')(X_shortcut)

# finaly
X = Add()([X, X_shortcut])
X = Activation('relu')(X)

return X

最后是 ResNet:

def ResNet( input_shape=(50, 50, 1), classes=10):
inp = Input(shape=(50,50,1))
# zero padding
X = ZeroPadding2D((3, 3), name='pad0')(inp)

# stage1
X = Conv2D(32, (5,5), name='conv1', input_shape=input_shape,
           kernel_initializer=initializers.glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name='bn1')(X)
X = Activation('relu')(X)
X = MaxPooling2D((2,2), name='pool1')(X)

# Stage 2
stage2_filtersize = 32
X = conv_block(X, 3, filters=[stage2_filtersize, stage2_filtersize, stage2_filtersize], stage=2, block='a', s=1)
X = identity_block(X, 3, [stage2_filtersize,stage2_filtersize, stage2_filtersize], stage=2, block='b')
X = identity_block(X, 3, [stage2_filtersize, stage2_filtersize, stage2_filtersize], stage=2, block='c')

# Stage 3
stage3_filtersize = 64
X = conv_block(X, 3, filters=[stage3_filtersize, stage3_filtersize, stage3_filtersize], stage=3, block='a', s=1)
X = identity_block(X, 3, [stage3_filtersize, stage3_filtersize, stage3_filtersize], stage=3, block='b')
X = identity_block(X, 3, [stage3_filtersize, stage3_filtersize, stage3_filtersize], stage=3, block='c')

# Stage 4
stage4_filtersize = 128
X = conv_block(X, 3, filters=[stage4_filtersize, stage4_filtersize, stage4_filtersize], stage=4, block='a', s=1)
X = identity_block(X, 3, [stage4_filtersize, stage4_filtersize, stage4_filtersize], stage=4, block='b')
X = identity_block(X, 3, [stage4_filtersize, stage4_filtersize, stage4_filtersize], stage=4, block='c')

# final
X = AveragePooling2D((2, 2), padding='same', name='Pool0')(X)

# FC
X = Flatten(name='D0')(X)
X = Dense(classes, activation='softmax', kernel_initializer=initializers.glorot_uniform(seed=0), name='D2')(X)

# creat model

model = Model(inputs=inp, outputs=X)

return model

更新1:这里是拟合和编译方法:

model.compile(optimizer='adam',
          loss=tensorflow.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
          metrics=['accuracy'])

model.compile(optimizer='adam',
          loss=tensorflow.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
          metrics=['accuracy'])

print("model compiled settings imported successfully")
early_stopping = EarlyStopping(monitor='val_loss', patience=2)

model.fit(X_train, Y_train, validation_split=0.2, callbacks=[early_stopping], epochs=10)

test_loss, test_acc = model.evaluate(X_test, Y_test, verbose=2)

【问题讨论】:

  • 请包含有关如何训练模型的代码
  • 图片标准化了吗?
  • 亲爱的马蒂亚斯@MatiasValdenegro。我在“update1”中添加了模型训练设置。
  • 亲爱的文卡塔@VenkataKrishnan。不,图像未标准化。

标签: opencv tensorflow keras computer-vision resnet


【解决方案1】:

首先尝试标准化数字图像 (50x50) 的值。

然后还要考虑神经网络如何学习其权重。 卷积神经网络通过不断添加梯度误差向量进行学习,这些梯度误差向量乘以学习率计算反向传播到各种整个网络的权重矩阵作为训练样本通过。

要考虑的最重要的事情是学习率的乘积,因为一旦我们不对训练输入进行缩放,特征值的分布范围很可能与每个特征不同,因此,学习率会导致每个维度的校正相互不同。这是随机的,因此机器可能在一个重量维度上过度补偿校正而在另一个重量维度上补偿不足。这是非常不理想的,因为这可能会导致振荡状态或非常慢的训练状态

振荡意味着模型无法定位中心以获得更好的权重最大值。
慢速训练意味着也移动缓慢达到更好的最大值。

这就是为什么在将图像用作神经网络或任何模型的输入之前标准化图像是一种常见做法基于梯度。

【讨论】:

  • 谢谢你的好回答。规范化解决了我的问题。:)
【解决方案2】:
  • TF_Support 的回答:

提供一些数据集、损失曲线、准确度图的样本,以便我们清楚地了解您要学习的内容,这比您提供的代码更重要。

我猜,你正在尝试学习非常难的样本,50×50 灰度并不多。你的网络过拟合了吗? (我们只能在查看一些验证指标图后才能弄清楚)(0.2 是您的训练准确度吗?)

首先通过训练一个非常简单的 CNN 对数据集进行完整性检查。我看到你有 10 个类(不确定,只是根据函数的默认值猜测),随机准确率为 10%,所以先用简单的 CNN 设置基线,然后尝试用 ResNet 改进。

提高学习率,看看准确率如何波动。在经过几个 epoch 后,当准确率优于基线时,降低学习率。

【讨论】:

  • 是的,实际上首先,我从一个简单的 CNN 开始,并让学习率被选为默认值。但我没有考虑如上所述对图像进行标准化。谢谢你的回答:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
  • 2020-05-27
  • 1970-01-01
  • 2020-02-01
  • 1970-01-01
  • 2023-03-16
相关资源
最近更新 更多