Tensorflow运行报错

我使用Tensorflow2.0搭建了了一个Tensorflow v1的LSTM神经网络结构,但是一直有一个错误解决不掉,请帮帮我,报错如下:

Traceback (most recent call last):
File “D:/python project/Machine_learning/Tensorflow_1/RNN_LSTM_回归.py”, line 117, in
model = LSTMRNN(TIME_STEPS, INPUT_SIZE, OUTPUT_SIZE, CELL_SIZE, BATCH_SIZE)
File “D:/python project/Machine_learning/Tensorflow_1/RNN_LSTM_回归.py”, line 55, in init
self.add_output_layer()
File “D:/python project/Machine_learning/Tensorflow_1/RNN_LSTM_回归.py”, line 84, in add_output_layer
ws_out = self._weights_variable([self.cell_size,self.output_size])
File “D:/python project/Machine_learning/Tensorflow_1/RNN_LSTM_回归.py”, line 110, in _weights_variable
return tf.get_variable(name=name, shape=shape, initializer=initializer)
File “D:\Anaconda3\envs\pytorch\lib\site-packages\tensorflow\python\ops\variable_scope.py”, line 1579, in get_variable
return get_variable_scope().get_variable(
File “D:\Anaconda3\envs\pytorch\lib\site-packages\tensorflow\python\ops\variable_scope.py”, line 1322, in get_variable
return var_store.get_variable(
File “D:\Anaconda3\envs\pytorch\lib\site-packages\tensorflow\python\ops\variable_scope.py”, line 578, in get_variable
return _true_getter(
File “D:\Anaconda3\envs\pytorch\lib\site-packages\tensorflow\python\ops\variable_scope.py”, line 531, in _true_getter
return self._get_single_variable(
File “D:\Anaconda3\envs\pytorch\lib\site-packages\tensorflow\python\ops\variable_scope.py”, line 894, in _get_single_variable
raise ValueError("%s Originally defined at:\n\n%s" %
ValueError: Variable weights already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:

File “D:\Anaconda3\envs\pytorch\lib\site-packages\tensorflow\python\framework\ops.py”, line 2101, in init
self._traceback = tf_stack.extract_stack_for_node(self._c_op)
File “D:\Anaconda3\envs\pytorch\lib\site-packages\tensorflow\python\framework\ops.py”, line 3697, in _create_op_internal
ret = Operation(
File “D:\Anaconda3\envs\pytorch\lib\site-packages\tensorflow\python\framework\op_def_library.py”, line 744, in _apply_op_helper
op = g._create_op_internal(op_type_name, inputs, dtypes=None,
File “D:\Anaconda3\envs\pytorch\lib\site-packages\tensorflow\python\ops\gen_state_ops.py”, line 1750, in variable_v2
_, _, _op, _outputs = _op_def_library._apply_op_helper(
File “D:\Anaconda3\envs\pytorch\lib\site-packages\tensorflow\python\ops\state_ops.py”, line 74, in variable_op_v2
return gen_state_ops.variable_v2(

附上源代码:

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
import numpy as np

BATCH_START = 0
TIME_STEPS = 20 # 每一次BATCH_SIZE的RNN CELL数量
BATCH_SIZE = 50 # 每次传入50个数据
INPUT_SIZE = 1 # 在每一个input是y的值,而每个点对应的y值只有1个,在每个时间点,只有1个y
OUTPUT_SIZE = 1 # 在每个时间点上有1个y
CELL_SIZE = 10 # 一个RNN CELL的隐藏层神经元个数
LR = 0.006
BATCH_START_TEST = 0

class LSTMRNN(object):
    # n_steps:一个batch内执行多少步,即RNN CELL个数
    # input_size:xs的长度,本例中为1
    # output_size:ys的长度,本例中为1
    # cell_size:cell中的hidden神经元个数
    # batch_size

    def __init__(self, n_steps, input_size, output_size, cell_size, batch_size):
        self.n_steps = n_steps
        self.input_size = input_size
        self.output_size = output_size
        self.cell_size = cell_size
        self.batch_size = batch_size
        with tf.name_scope('inputs'):
            self.xs = tf.placeholder(tf.float32, [None, n_steps, input_size], name='xs')
            self.ys = tf.placeholder(tf.float32, [None, n_steps, output_size], name='ys')
        with tf.name_scope('in_hidden'):
            self.add_input_layer()
        with tf.name_scope('LSTM_cell'):
            self.add_cell()
        with tf.name_scope('out_hidden'):
            self.add_output_layer()
        with tf.name_scope('cost'):
            self.compute_cost()
        with tf.name_scope('train'):
            self.train_op = tf.train.AdamOptimizer(LR).minimize(self.cost)

    def add_input_layer(self):
        l_in_x = tf.reshape(self.xs,[-1,self.input_size],name='2-2D') # 3维-->2维(batch*n_steps,input_size)
        ws_in = self._weights_variable([self.input_size,self.cell_size]) # Ws(in_size,cell_size)
        bs_in = self._biases_variable([self.cell_size,]) # bs(cell_size,)
        with tf.name_scope('Wx_plus_a'):
             l_in_y = tf.matmul(l_in_x, ws_in) + bs_in # l_in_y = (batch*n_steps,cell_size)
        # ad_cell层可以接受3D数据输入,因此还需要将2D转换回3D
        # reshape l_in_y-->(batch,n_steps,cell_size)
        self.l_in_y = tf.reshape(l_in_y, [-1, self.n_steps, self.cell_size], name='2-3D')

    def add_cell(self):
        lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)
        with tf.name_scope('initial_state'):
            self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32) # 初始化的state是全为0的
        self.cell_outputs,self.cell_final_state = tf.nn.dynamic_rnn(
            lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
        # 某一个batch的initial_state是上一个batch的self.cell_init_state
        # self.cell_outputs = (batch,n_steps,cell_size)

    def add_output_layer(self):
        # 和add_input_layer相似,需要先将数据降维成2D
        # shape = (batch * steps,cell_size)
        l_out_x = tf.reshape(self.cell_outputs,[-1,self.cell_size],name='4-2D')
        ws_out = self._weights_variable([self.cell_size,self.output_size])
        bs_out = self._biases_variable([self.output_size,]) # shape = (batch * steps,output_size)
        with tf.name_scope('Wx_plus_b'):
            self.pred = tf.matmul(l_out_x,ws_out) + bs_out

    def compute_cost(self): # batch的每一步loss
        losses = tf.nn.seq2seq.sequence_loss_by_example(
            [tf.reshape(self.pred,[-1],name='reshape_pred')],
            [tf.reshape(self.ys,[-1],name='reshape_target')],
            [tf.ones([self.batch_size * self.n_steps],dtype=tf.float32)],
            average_across_timesteps=True,
            softmax_loss_function=self.ms_error,
            name='losses'
        )
        with tf.name_scope('average_cost'): # 将每一个batch的误差相加之后,在除以batch_size得到平均误差
            self.cost = tf.div(
                tf.reduce_sum(losses, name='losses_sum'),
                tf.cast(self.batch_size, tf.float32),
                name='average_cost')
            tf.scalar_summary('cost', self.cost)

    def ms_error(self, y_pre, y_target):
        return tf.square(tf.sub(y_pre, y_target))

    def _weights_variable(self, shape, name='weights'):
        initializer = tf.random_normal_initializer(mean=0., stddev=1.,)
        return tf.get_variable(name=name, shape=shape, initializer=initializer)

    def _biases_variable(self, shape1, name1='biases'):
        initializer = tf.constant_initializer(0.1)
        return tf.get_variable(name=name1, shape=shape1, initializer=initializer)

如错误提示所述,你这里在add_output_layer里面使用了之前已经使用过的self._weights_variable,但又没有设置reuse。这是TF 1.X中比较有代表性的问题。可以参考 https://mp.weixin.qq.com/s?__biz=MzU1OTMyNDcxMQ==&mid=2247487599&idx=1&sn=13a53532ad1d2528f0ece4f33e3ae143&chksm=fc185b27cb6fd2313992f8f2644b0a10e8dd7724353ff5e93a97d121cd1c7f3a4d4fcbcb82e8&scene=178&cur_album_id=1338132220393111552#rd 中关于“变量的作用域与重用”以及reuse参数相关的内容。

如果你其实并不熟悉TF 1.X,建议从2.X开始学习,现在的TensorFlow已经不会有这些问题了。