![](/img/trans.png)
[英]What should be the input to Convolution neural network (CNN) using keras and tensorflow?
[英]Find input that maximises output of a neural network using Keras and TensorFlow
按照本教程<\/a>,我使用 Keras 和 TensorFlow 对Fashion MNIST<\/a>进行分类。
它使用AdamOptimizer<\/a>来找到模型参数的值,以最小化网络的损失函数。 网络的输入是一个形状为 [28, 28] 的二维张量,输出是一个形状为 [10] 的一维张量,它是 softmax 函数的结果。
一旦网络经过训练,我想将优化器用于另一项任务:找到一个使输出张量的一个元素最大化的输入。 如何才能做到这一点? 是否可以使用 Keras 来做到这一点,或者必须使用较低级别的 API?
由于输入对于给定的输出不是唯一的,如果我们可以对输入可以采用的值施加一些限制,那就更好了。
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(10, activation=tf.nn.softmax)
])
它与可视化卷积网络的滤波器的方式非常相似:我们将在输入空间中进行梯度上升优化,以最大化特定滤波器的响应 。
以下是如何操作:训练结束后,首先我们需要指定输出并定义一个我们想要最大化的损失函数:
from keras import backend as K
output_class = 0 # the index of the output class we want to maximize
output = model.layers[-1].output
loss = K.mean(output[:,output_class]) # get the average activation of our desired class over the batch
接下来,我们需要采用上面针对输入层定义的损失的梯度:
grads = K.gradients(loss, model.input)[0] # the output of `gradients` is a list, just take the first (and only) element
grads = K.l2_normalize(grads) # normalize the gradients to help having an smooth optimization process
接下来,我们需要定义一个后端函数,它接受初始输入图像并将损失和梯度值作为输出,以便我们可以在下一步中使用它来实现优化过程:
func = K.function([model.input], [loss, grads])
最后,我们实现了渐变上升优化过程:
import numpy as np
input_img = np.random.random((1, 28, 28)) # define an initial random image
lr = 1. # learning rate used for gradient updates
max_iter = 50 # number of gradient updates iterations
for i in range(max_iter):
loss_val, grads_val = func([input_img])
input_img += grads_val * lr # update the image based on gradients
请注意,在此过程完成后,要显示图像,您可能需要确保图像中的所有值都在[0,255](或[0,1])范围内。
有趣。 也许解决方案是将所有数据提供给网络,并且每个样本在softmax
之后保存output_layer
。
这样一来,对于3类 ,要找到1类最佳的投入,你正在寻找的输出,其中第一部分是高的。 例如: [1 0 0]
实际上,输出意味着样本是其中一个类的概率或网络的置信度。
在Saket Kumar Singh给出答案的提示之后,我写下了似乎可以解决问题的以下内容。
我创建了两个自定义图层。 也许Keras已经提供了一些与它们相当的类。
第一个是可训练的输入:
class MyInputLayer(keras.layers.Layer):
def __init__(self, output_dim, **kwargs):
self.output_dim = output_dim
super(MyInputLayer, self).__init__(**kwargs)
def build(self, input_shape):
self.kernel = self.add_weight(name='kernel',
shape=self.output_dim,
initializer='uniform',
trainable=True)
super(MyInputLayer, self).build(input_shape)
def call(self, x):
return self.kernel
def compute_output_shape(self, input_shape):
return self.output_dim
第二个获得感兴趣的标签的概率:
class MySelectionLayer(keras.layers.Layer):
def __init__(self, position, **kwargs):
self.position = position
self.output_dim = 1
super(MySelectionLayer, self).__init__(**kwargs)
def build(self, input_shape):
super(MySelectionLayer, self).build(input_shape)
def call(self, x):
mask = np.array([False]*x.shape[-1])
mask[self.position] = True
return tf.boolean_mask(x, mask,axis=1)
def compute_output_shape(self, input_shape):
return self.output_dim
我用这种方式使用它们:
# Build the model
layer_flatten = keras.layers.Flatten(input_shape=(28, 28))
layerDense1 = keras.layers.Dense(128, activation=tf.nn.relu)
layerDense2 = keras.layers.Dense(10, activation=tf.nn.softmax)
model = keras.Sequential([
layer_flatten,
layerDense1,
layerDense2
])
# Compile the model
model.compile(optimizer=tf.train.AdamOptimizer(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# Train the model
# ...
# Freeze the model
layerDense1.trainable = False
layerDense2.trainable = False
# Build another model
class_index = 7
layerInput = MyInputLayer((1,784))
layerSelection = MySelectionLayer(class_index)
model_extended = keras.Sequential([
layerInput,
layerDense1,
layerDense2,
layerSelection
])
# Compile it
model_extended.compile(optimizer=tf.train.AdamOptimizer(),
loss='mean_absolute_error')
# Train it
dummyInput = np.ones((1,1))
target = np.ones((1,1))
model_extended.fit(dummyInput, target,epochs=300)
# Retrieve the weights of layerInput
layerInput.get_weights()[0]
有趣的巧合我只是在研究同样的“问题”。 我对对抗训练的方向感兴趣等。我做的是在输入后插入一个LocallyConnected2D
图层,然后训练所有的数据,并将目标作为感兴趣的类。
作为我使用的模型
batch_size = 64
num_classes = 10
epochs = 20
input_shape = (28, 28, 1)
inp = tf.keras.layers.Input(shape=input_shape)
conv1 = tf.keras.layers.Conv2D(32, kernel_size=(3, 3),activation='relu',kernel_initializer='he_normal')(inp)
pool1 = tf.keras.layers.MaxPool2D((2, 2))(conv1)
drop1 = tf.keras.layers.Dropout(0.20)(pool1)
flat = tf.keras.layers.Flatten()(drop1)
fc1 = tf.keras.layers.Dense(128, activation='relu')(flat)
norm1 = tf.keras.layers.BatchNormalization()(fc1)
dropfc1 = tf.keras.layers.Dropout(0.25)(norm1)
out = tf.keras.layers.Dense(num_classes, activation='softmax')(dropfc1)
model = tf.keras.models.Model(inputs = inp , outputs = out)
model.compile(loss=tf.keras.losses.categorical_crossentropy,
optimizer=tf.keras.optimizers.RMSprop(),
metrics=['accuracy'])
model.summary()
训练后我插入新图层
def insert_intermediate_layer_in_keras(model,position, before_layer_id):
layers = [l for l in model.layers]
if(before_layer_id==0) :
x = new_layer
else:
x = layers[0].output
for i in range(1, len(layers)):
if i == before_layer_id:
x = new_layer(x)
x = layers[i](x)
else:
x = layers[i](x)
new_model = tf.keras.models.Model(inputs=layers[0].input, outputs=x)
return new_model
def fix_model(model):
for l in model.layers:
l.trainable=False
fix_model(model)
new_layer = tf.keras.layers.LocallyConnected2D(1, kernel_size=(1, 1),
activation='linear',
kernel_initializer='he_normal',
use_bias=False)
new_model = insert_intermediate_layer_in_keras(model,new_layer,1)
new_model.compile(loss=tf.keras.losses.categorical_crossentropy,
optimizer=tf.keras.optimizers.RMSprop(),
metrics=['accuracy'])
最后用我的假数据重新训练。
X_fake = np.ones((60000,28,28,1))
print(Y_test.shape)
y_fake = np.ones((60000))
Y_fake = tf.keras.utils.to_categorical(y_fake, num_classes)
new_model.fit(X_fake, Y_fake, epochs=100)
weights = new_layer.get_weights()[0]
imshow(weights.reshape(28,28))
plt.show()
结果还不令人满意,但我对这种方法充满信心并猜测我需要与优化器一起玩。
对于密集模型,您可以像本文一样可视化输入的影响
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.