我试图在tensorflow中构建一个CNN,它将矢量作为输入ex:
x = [4,1,1,1,1,2,1,2,1,1,1,2,2,1,1,3],
整数代表名义编码。
并输出值已移位的向量,例如:
y = [0,4,1,1,1,2,1,2,1,1,1,2,2,1,1,3]
在这种情况下,4的位置是向量中的变化变量。
问题:
这是否可以创建一个返回该格式输出的convnet?我只见过应用于分类问题的转移。
在这些情况下,我如何定义/计算错误?我是否需要知道y的潜在值的数量?
答案 0 :(得分:1)
如何使用TensorFlow(可能还有Convolution)来玩棋盘游戏?
具体来说,我有一块小板(4x4或16x1),可能的值为[0,1,2,3,4],我想知道下一个最佳动作。
你所要求的与what DeepMind did with AlphaGo没什么不同,但也许你不需要所有的花里胡哨。回顾DeepMind如何安排他们的架构将让您深入了解如何在游戏中应用类似的策略。
在较高的水平上,他们使用1个神经网络对当前的电路板配置(值网络)进行评级,并使用另一个神经网络来建议可能的下一个最佳移动(策略网络 em>)和搜索。
是的,您可以使用此配置进入城镇,您的系统可能会玩一个非常棒的游戏。
我是工程师,因此我希望立即看到一些结果,这就是本节的真正含义。
我使用简单的AlphaBeta(由MIT跟随this lecture构建)为棋子编程AI。我从这开始,将AlphaBeta应用到您的棋盘游戏并硬编码值函数。例如,棋子中的值函数可能“比你的对手有更多的棋子”。
如果 N + 1 前瞻通常胜过 N 前瞻
,您就会知道自己是否已经很好地实施了那么是TensorFlow的时候了!使用硬编码值函数和几个前瞻作为良好移动的训练集。从TensorFlow训练CNN以正确地衡量较高的前瞻动作的高度。
具体来说,对于前瞻1中的移动A和前瞻2中的移动B与前瞻3中的移动C,您的CNN应该使用最高值移动C,然后移动B,然后移动A,然后移动所有其他可能的移动。
如果您可以通过硬编码策略让CNN重视移动3前瞻,那么当您的硬编码策略有3个前瞻时,您的CNN在一个前瞻中有效地具有硬编码策略的强大功能。
现在,请关闭您的硬编码政策并输入您的CNN版本1。
像对待版本1一样迭代并训练您的CNN版本2.
以上只是为了得到一些东西。它不会重新创建AlphaGo。调查像Go这样非常开放的游戏的Monte Carlo method。还要进一步调查“策略网络”以生成可能的下一步行动,而不是仅在生成后对其进行评分。
祝你好运!使用
之类的东西将所有这些数字[0,1,2,3,4]转换为1热编码board = tf.constant( [4, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 3] , dtype=tf.int16 )
board_as_mask = tf.one_hot( board , 5 )
sess = tf.Session()
sess.run(board_as_mask)
array([[ 0., 0., 0., 0., 1.],
[ 0., 1., 0., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 0., 1., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 0., 1., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 0., 1., 0., 0.],
[ 0., 0., 1., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 0., 0., 1., 0.]], dtype=float32)
误差通常是平方和( y _ - y )^ 2或交叉熵 y _ * log( y < /强>)。不需要做任何比这更花哨的事情。 y _ 可能是“这是一个N前瞻选择N-1不会”的举动,或者如果你使用蒙特卡罗,它可能是“这一举动会导致胜利吗? “
您可以使用embedding_lookup(例如 tf.nn.embedding_lookup )代替使用1-hot编码,并使用数千个随机初始化的项目填充它。如果在训练期间它遇到一个新项目,那么它将开始更新相应的嵌入。
如果你想使用嵌入查找(这可能有很大的优势),你可以用这样的东西启动它:
board = tf.constant( [4, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 3] , dtype=tf.int32 )
index_max = 10
features = 3
embeddings = tf.Variable( tf.truncated_normal( [index_max, features] , dtype=tf.float32 ) )
board_as_embeddings = tf.nn.embedding_lookup(embeddings, board)
sess = tf.Session()
sess.run(tf.global_variables_initializer() )
print sess.run(board_as_embeddings)
和输出
[[-0.29756528 1.25859058 -1.68821394]
[ 0.19683863 1.09903252 -1.12252223]
[ 0.19683863 1.09903252 -1.12252223]
[ 0.19683863 1.09903252 -1.12252223]
[ 0.19683863 1.09903252 -1.12252223]
[ 1.07770884 -1.47092581 -1.85934114]
[ 0.19683863 1.09903252 -1.12252223]
[ 1.07770884 -1.47092581 -1.85934114]
[ 0.19683863 1.09903252 -1.12252223]
[ 0.19683863 1.09903252 -1.12252223]
[ 0.19683863 1.09903252 -1.12252223]
[ 1.07770884 -1.47092581 -1.85934114]
[ 1.07770884 -1.47092581 -1.85934114]
[ 0.19683863 1.09903252 -1.12252223]
[ 0.19683863 1.09903252 -1.12252223]
[-0.34236383 1.67817557 -1.54652882]]
这会将每个游戏位置转换为功能的语义字段,在本例中为3.
以下是使用冻湖
进行原始问题的一些代码import tensorflow as tf
index_max = 10
features = 5
width = 4
size = width*width
x_data = [[4, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 3],
[0, 1, 1, 1, 1, 2, 1, 4, 1, 1, 1, 2, 2, 1, 1, 3]]
y_data = [[0, 4, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 3],
[0, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 2, 2, 4, 1, 3]]
x_input = tf.placeholder( shape=[None,size] , dtype=tf.int32 )
y_ground = tf.placeholder( shape=[None,size] , dtype=tf.int32 )
embedding_vector = tf.Variable( tf.truncated_normal( [index_max, features] , dtype=tf.float32 ) )
embedding_vector_3_ranks = tf.reshape(embedding_vector, [1,index_max, features])
x_embedding = tf.nn.embedding_lookup(embedding_vector, x_input)
def conv_layer( x , layers_in=features , layers_out=features ):
strides = [1, 1, 1, 1]
w = tf.Variable( tf.truncated_normal([3,3,layers_in, layers_out], stddev=0.1, dtype=tf.float32) )
b = tf.Variable( tf.constant(0.1, shape=[layers_out], dtype=tf.float32) )
h = tf.nn.conv2d( x, w, strides=[1, 1, 1, 1], padding='SAME' ) + b
return h # tf.nn.relu( h )
hidden = tf.reshape( x_embedding, [-1,width,width,features] )
hidden = tf.nn.relu( conv_layer( hidden ) )
hidden = tf.nn.relu( conv_layer( hidden ) )
hidden = tf.nn.relu( conv_layer( hidden ) )
y_output = tf.reshape( conv_layer( hidden ) , [-1,features] )
item_as_embedding = tf.tile( y_output , tf.constant([1,index_max]) )
item_as_embedding = tf.reshape( item_as_embedding , [-1,index_max,features] )
item_distance_to_embedding = tf.square( embedding_vector_3_ranks - item_as_embedding )
item_distance_to_embedding = tf.reduce_mean( item_distance_to_embedding , -1 )
item_distance_to_embedding = tf.reshape( item_distance_to_embedding, [-1,index_max] )
y_estimate = tf.arg_max( -1.0 * tf.reduce_mean( tf.square( tf.reshape( embedding_vector, [1,index_max, features]) - item_as_embedding ) , -1 ) , 1 )
mask = tf.reshape( tf.one_hot(y_ground,index_max, dtype=tf.float32) , [-1,index_max] )
error = tf.reduce_sum( mask * item_distance_to_embedding , -1 )
learn = tf.train.AdamOptimizer(0.001).minimize(error)
sess = tf.Session()
sess.run(tf.global_variables_initializer() )
for _ in range(20) :
feed_dict = { x_input : x_data, y_ground : y_data }
print sess.run(y_estimate,feed_dict).reshape([-1,size]) , sess.run(tf.reduce_sum(error,-1),feed_dict)
for _ in range(20) :
sess.run(learn,feed_dict)