称重面罩/重量调整在keras

时间:2019-02-27 13:43:52

标签: tensorflow keras conv-neural-network attention-model

我想提供一个与输入图像大小相同的蒙版,并根据该蒙版调整从图像中获知的权重(类似于注意,但针对每个图像输入进行了预先计算)。我该如何使用keras(或tensorflow)做到这一点?

1 个答案:

答案 0 :(得分:2)

问题

如何向图像中添加另一个特征层(如“蒙版”),并使神经网络将这一新的特征层考虑在内?

答案

最简单的答案是将其添加为图像的另一个颜色通道。如果您的图像已经具有3个颜色通道;红色,蓝色,绿色,然后添加遮罩的1和0的另一个通道,可以为神经网络提供更多信息来进行决策。

思想实验

作为思想实验,让我们解决MNIST。 MNIST图片为28x28。让我们拍摄1张图像(“真实”图像)和3张其他图像(“干扰”图像),形成4张28x28图像中的56x56图像。 MNIST是黑白的,因此只有1个颜色通道,即亮度。现在,让我们添加另一个颜色通道,即遮罩,在56x56图像的“真实”图像所在的区域中为1,在其他位置的0为其他颜色。

如果我们使用与往常一样的体系结构来解决MNIST,并一直进行卷积,我们可以想象它可以使用这一新信息来学习仅关注“真实”区域并正确地对图像进行分类。 / p>

代码示例

在此示例中,我们尝试解决XOR问题。我们采用经典的异或运算,将输入的噪声加倍,并为非噪声添加一个1的通道,为噪声添加一个0的通道


# Adapted from https://github.com/panchishin/learn-to-tensorflow/blob/master/solutions/04-xor-2d.py

# -- The xor problem --
x = np.array([[0., 0.], [1., 1.], [1., 0.], [0., 1.]])
y_ = [[1., 0.], [1., 0.], [0., 1.], [0., 1.]]


def makeBatch() :
    # Add an additional 2 channels of noise
    # either before or after the two real 'x's.
    global x
    rx = np.random.rand(4,4,2) > 0.5
    # set the mask to 0 for all items
    rx[:,:,1] = 0
    index = int(np.random.random()*3)
    rx[:,index:index+2,0] = x
    # set the mask to 1 for 'real' values
    rx[:,index:index+2,1] = 1
    return rx

# -- imports --
import tensorflow as tf

# np.set_printoptions(precision=1) reduces np precision output to 1 digit
np.set_printoptions(precision=2, suppress=True)


# -- induction --

# Layer 0
x0 = tf.placeholder(dtype=tf.float32, shape=[None, 4, 2])
y0 = tf.placeholder(dtype=tf.float32, shape=[None, 2])

# Layer 1
f1 = tf.reshape(x0,shape=[-1,8])
m1 = tf.Variable(tf.random_uniform([8, 9], minval=0.1, maxval=0.9, dtype=tf.float32))
b1 = tf.Variable(tf.random_uniform([9], minval=0.1, maxval=0.9, dtype=tf.float32))
h1 = tf.sigmoid(tf.matmul(f1, m1) + b1)

# Layer 2
m2 = tf.Variable(tf.random_uniform([9, 2], minval=0.1, maxval=0.9, dtype=tf.float32))
b2 = tf.Variable(tf.random_uniform([2], minval=0.1, maxval=0.9, dtype=tf.float32))
y_out = tf.nn.softmax(tf.matmul(h1, m2) + b2)


# -- loss --

# loss : sum of the squares of y0 - y_out
loss = tf.reduce_sum(tf.square(y0 - y_out))

# training step : gradient descent (1.0) to minimize loss
train = tf.train.GradientDescentOptimizer(1.0).minimize(loss)



# -- training --
# run 500 times using all the X and Y
# print out the loss and any other interesting info
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    print("\nloss")
    for step in range(5000):
        sess.run(train, feed_dict={x0: makeBatch(), y0: y_})
        if (step + 1) % 1000 == 0:
            print(sess.run(loss, feed_dict={x0: makeBatch(), y0: y_}))

    results = sess.run([m1, b1, m2, b2, y_out, loss], feed_dict={x0: makeBatch(), y0: y_})
    labels = "m1,b1,m2,b2,y_out,loss".split(",")
    for label, result in zip(*(labels, results)):
        print("")
        print(label)
        print(result)

print("")

输出

我们可以看到网络能够正确解决问题,并高度肯定地提供正确的输出

y_(真相)= [[1.,0.],[1.,0.],[0.,1.],[0.,1。]]

y_out
[[0.99 0.01]
 [0.99 0.01]
 [0.01 0.99]
 [0.01 0.99]]

loss
0.00056630466

确认面具在做某事

让我们更改遮罩功能,以便通过注释掉将噪声设置为0并将信号设置为1的行来使其随机化

def makeBatch() :
    global x
    rx = np.random.rand(4,4,2) > 0.5
    #rx[:,:,1] = 0
    index = int(np.random.random()*3)
    rx[:,index:index+2,0] = x
    #rx[:,index:index+2,1] = 1
    return rx

,然后重新运行代码。确实,我们可以看到没有面具就无法学习网络。

y_out
[[0.99 0.01]
 [0.76 0.24]
 [0.09 0.91]
 [0.58 0.42]]

loss
0.8080765

结论

如果图像(或其他数据结构)中有一些信号和噪声,并成功添加了另一个通道(掩码),该通道指示信号的位置和噪声的位置,则神经网络可以利用该掩码来聚焦信号上的噪声仍然可以访问。