【发布时间】:2020-02-08 04:21:59
【问题描述】:
任务:给定 {0,1,2,3,4} 的随机序列号,训练一个神经网络以找到数字“2”的位置索引。该网络模仿中值滤波器,它找到中值的索引而不是中值本身。例如,给定输入 [3,1,0,2,4],输出/标签为“3”(或 [0,0,0,1,0])。
我可以通过设置内核和偏置权重来手动构建一个简单的神经网络来完成这项工作。它完美地完成了这项工作。 keras 代码如下:
val_len = 5
def GetModel():
inputs_img = keras.layers.Input(shape=(val_len, 1), name='rank')
net = keras.layers.Conv1D(1, 1, activation='tanh', name='layer1', trainable=True, kernel_initializer=keras.initializers.RandomUniform(-5, 5), bias_initializer=keras.initializers.RandomUniform(-5, 5))(inputs_img)
net = keras.layers.Lambda(lambda x: K.abs(x))(net)
net = keras.layers.Conv1D(1, 1, activation='relu', name='layer2', trainable=True, kernel_initializer=keras.initializers.RandomUniform(-5, 5), bias_initializer=keras.initializers.RandomUniform(-5, 5))(net)
net = keras.layers.Flatten()(net)
net = keras.layers.Dense(units=val_len, name = 'mid_pos', activation='softmax', trainable=True, kernel_initializer=keras.initializers.RandomUniform(-5, 5), bias_initializer=keras.initializers.RandomUniform(-5, 5))(net)
model = keras.models.Model(inputs=[inputs_img], outputs=[net])
return model
model = GetModel()
# do 2 - x
model.get_layer('layer1').set_weights([np.array([[[-1]]], dtype=np.float32), np.array([2], dtype=np.float32)])
# do 1 - x
model.get_layer('layer2').set_weights([np.array([[[-1]]], dtype=np.float32), np.array([1], dtype=np.float32)])
# do 1-to-1 connection
model.get_layer('mid_pos').set_weights([np.array([[1,0,0,0,0],
[0,1,0,0,0],
[0,0,1,0,0],
[0,0,0,1,0],
[0,0,0,0,1]], dtype=np.float32),
np.array([0,0,0,0,0], dtype=np.float32)])
但是,这个简单的模型无法从示例中学习权重(我尝试了许多优化器)。它可以达到的最佳精度是 0.2,这是从 5 个类别中随机选择的。如果我们手动分配“layer2”和“mid_pos”层的权重,模型就可以开始学习“layer1”了。
我的问题是:1.为什么这个简单的模型不能从例子中学习? 2.如何提高学习能力?谢谢你的cmets。 (顺便说一句,广义的 cnn 不是解决方案)
【问题讨论】:
-
看来你的初始化器非常大。让标准初始化器代替。
-
另外,您正在使用带有如此微小维度数据的 relu。用它获得全零的机会很大。 (虽然在这种情况下你在它之前使用了
abs,使得“relu”没用) -
我进行了更正,密集单位=5(我之前打错了)。我使用 loss='categorical_crossentropy' 作为优化器。你的意思是 abs 操作使梯度的反向传播失败?我同意“layer2”中的“relu”并不重要,但“abs”操作不会损害“relu”履行职责。我可以做一些归一化来适应0~1的数据,但这并不能解决问题。
-
Relu 改变低于 0 的值。abs 后没有任何低于 0 的值。
-
relu 不适用于 abs 层,它适用于 layer2。如果 layer2 有负权重或偏差,relu 肯定会在输出上完成它的工作。当然,对于分配的权重,relu 与线性相同。无论如何,这里的 relu 不会导致模型“无法训练”。
标签: tensorflow machine-learning keras neural-network