美文网首页
TensorFlow学习笔记(1)——低级API

TensorFlow学习笔记(1)——低级API

作者: for123 | 来源:发表于2018-05-16 22:01 被阅读0次

    学习目标

    • 张量
    • 变量
    • 保存和恢复

    基本概念

    TensorFlow的核心数据单位是张量,TensorFlow Core程序可以看作是两个相互独立的部分组成:构建计算图,运行计算图。

    张量

    一个张量由一组阵列(任意维数)的原始值组成。张量的阶是它的维数,而它的的形状是一个整数元组,制定了阵列每个维度的长度。

    1 #0阶张量(标量)
    [1,2] #1阶张量(向量)
    [[1,2],[3,4]] #2阶张量(矩阵)
    ......
    
    tf.Tensor具有的属性:
    • 数据类型(float32,int,string)
    • 形状

    张量中的每个元素都具有相同的数据类型,且数据类型一定是已知的。形状可能是部分已知。

    a = tf.constant(3.0, dtype=tf.float32) #定义一个常量
    b = tf.constant(4.0) # 数据类型也是tf.float32
    
    常用的特殊张量:
    • tf.Variable
    • tf.constant
    • tf.placeholder
    • tf.SparseTensor
      除tf.Variable意外,张量的值不可变。但同一张量在读取随机数等情况下可能返回不同值。

    tf.Tensor的阶就是它本身的维数,和数学中矩阵的阶并不是同一个概念。

    数学实例
    0 标量
    1 向量
    2 矩阵
    3 数据立体
    n n阶张量(脑补)
    • 0阶
    mammal = tf.Variable("Elephant", tf.string)
    ignition = tf.Variable(451, tf.int16)
    floating = tf.Variable(3.14159265359, tf.float64)
    its_complicated = tf.Variable(12.3 - 4.85j, tf.complex64)
    
    • 1阶
    mystr = tf.Variable(["Hello"], tf.string)
    cool_numbers  = tf.Variable([3.14159, 2.71828], tf.float32)
    first_primes = tf.Variable([2, 3, 5, 7, 11], tf.int32)
    its_very_complicated = tf.Variable([12.3 - 4.85j, 7.5 - 6.23j], tf.complex64)
    
    • 2阶
    mymat = tf.Variable([[7],[11]], tf.int16)
    myxor = tf.Variable([[False, True],[True, False]], tf.bool)
    linear_squares = tf.Variable([[4], [9], [16], [25]], tf.int32)
    squarish_squares = tf.Variable([ [4, 9], [16, 25] ], tf.int32)
    rank_of_squares = tf.rank(squarish_squares)
    mymatC = tf.Variable([[7],[11]], tf.int32)
    
    获取阶
    r = tf.rank(my_image) #计算图运行后,r将返回4
    
    切片
    my_scalar = my_vector[2] #1阶,返回标量
    my_scalar = my_matrix[1, 2] #2阶,返回标量
    my_row_vector = my_matrix[2] #2阶,返回行
    my_column_vector = my_matrix[:, 3] #2阶,返回列
    
    形状

    张量的形状是每个维度中元素的数量

    实例 形状 维数 说明
    1 0 [] 0-D 0维(阶)张量
    [1,2] 1 [2] 1-D 形状为[2]的1维(阶)张量
    [[1,2],[3,4,5]] 2 [2,3] 2-D 形状为[2,3]的2维(阶)张量
    [[[1,2],[3,4]],[[5,6,7],[8,9,10]]] 3 [2,2,2] 3-D 形状为[2,2,2]的3维(阶)张量
    ****** n [D0,...,Dn-1] n-D 形状为[D0,...,Dn-1]的n维(阶)张量
    获取形状
    c = tf.constant([1,2])
    printf(c.shape) #方法1,返回(2,)
    
    tf.shape(c) #方法2,返回TensorShapr目标,<tf.Tensor 'Shape:0' shape=(1,) dtype=int32>
    
    改变形状

    张量的元素数量是其所有形状大小的乘积,标量的元素数量永远是1。

    rank_three_tensor = tf.ones([3, 4, 5]) #创建一个3维,形状为(3,4,5)的张量
    matrix = tf.reshape(rank_three_tensor, [6, 10]) #重构成一个2维,形状为(6,10)的张量
    matrixB = tf.reshape(matrix, [3, -1]) #重构成一个2维,形状为(3,20)的张量
    matrixAlt = tf.reshape(matrixB, [4, 3, -1]) #重构成一个3维,形状为(4,3,,5)的张量
    yet_another = tf.reshape(matrixAlt, [13, 2, -1]) #元素数量不匹配,报错
    
    
    数据类型
    float_tensor = tf.cast(tf.constant([1, 2, 3]), dtype=tf.float32) #将int转换为float32
    printf(tf.constant([1, 2, 3]).dtype) #返回数据类型
    
    数据类型 Python类型 描述
    DT_FLOAT tf.float32 32 位浮点数.
    DT_DOUBLE tf.float64 64 位浮点数.
    DT_INT64 tf.int64 64 位有符号整型.
    DT_INT32 tf.int32 32 位有符号整型.
    DT_INT16 tf.int16 16 位有符号整型.
    DT_INT8 tf.int8 8 位有符号整型.
    DT_UINT8 tf.uint8 8 位无符号整型.
    DT_STRING tf.string 可变长度的字节数组.每一个张量元素都是一个字节数组.
    DT_BOOL tf.bool 布尔型.
    DT_COMPLEX64 tf.complex64 由两个32位浮点数组成的复数:实数和虚数.
    DT_QINT32 tf.qint32 用于量化Ops的32位有符号整型.
    DT_QINT8 tf.qint8 用于量化Ops的8位有符号整型.
    DT_QUINT8 tf.quint8 用于量化Ops的8位无符号整型.
    评估张量
    t = tf.constant(42.0)
    u = tf.constant(37.0)
    tu = tf.mul(t, u)
    ut = tf.mul(u, t)
    with sess.as_default():
       tu.eval()  # 执行一步
       ut.eval()  # 执行一步
       sess.run([tu, ut])  # 一步执行两个张量
    
    打印张量

    调试用

    x=tf.constant([2,3,4,5])  
    x=tf.Print(x,[x,x.shape,'any thing i want'],message='Debug message:',summarize=100)   
    with tf.Session() as sess:  
        sess.run(x)  
    
    
    输出:Debug message:[2 3 4 5][4][any thing i want]
    

    变量

    创建变量
    my_variable = tf.get_variable("my_variable", [1, 2, 3]) #初始值通过tf.glorot_uniform_initializer随机设置
    my_int_variable = tf.get_variable("my_int_variable", [1, 2, 3], dtype=tf.int32,initializer=tf.zeros_initializer) #指定类型和初始化器
    other_variable = tf.get_variable("other_variable", dtype=tf.int32,initializer=tf.constant([23, 42])) #使用张量的类型
    
    变量集合

    Tensorflow提供集合,放置变量。默认情况下,每个 tf.Variable 都放置在以下两个集合中:

    • tf.GraphKeys.GLOBAL_VARIABLES - 可以在多个设备共享的变量
    • tf.GraphKeys.TRAINABLE_VARIABLES - TensorFlow 将计算其梯度的变量。
    my_local = tf.get_variable("my_local", shape=(),collections=[tf.GraphKeys.LOCAL_VARIABLES]) # 添加到 tf.GraphKeys.LOCAL_VARIABLES 集合中
    my_non_trainable = tf.get_variable("my_non_trainable",shape=(),trainable=False) #  添加到 tf.GraphKeys.LOCAL_VARIABLES 集合中
    tf.add_to_collection("my_collection_name", my_local) #添加到自己命名的my_collection_name集合中
    tf.get_collection("my_collection_name") #检索该集合下所有变量
    
    设备放置方式
    ###将变量放置在第二个GPU设备上
    with tf.device("/device:GPU:1"):
       v = tf.get_variable("v", [1]) 
    
    分布式设置

    以后再更

    初始化变量
    ### 初始化tf.GraphKeys.GLOBAL_VARIABLES 集合中所有变量
    # 创建两个变量
    weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),
                          name="weights")
    biases = tf.Variable(tf.zeros([200]), name="biases")
    ...
    # 添加用于初始化变量的节点
    init_op = tf.global_variables_initializer()
    
    # 然后,在加载模型的时候
    with tf.Session() as sess:
      # 运行初始化操作
      sess.run(init_op)
      ...
      # 使用模型
      ...
    
    ### 自行初始化变量
    session.run(my_variable.initializer)
    print(session.run(tf.report_uninitialized_variables())) #查询哪些变量尚未初始化
    

    默认的 tf.global_variables_initializer 不会指定变量的初始化顺序。因此,如果变量的初始值取决于另一变量的值,那么很有可能会出现错误。

    # 使用随机数创建一个变量
    weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),name="weights")
    # 创建另一个变量,它与weights拥有相同的初始值
    w2 = tf.Variable(weights.initialized_value(), name="w2")
    # 创建另一个变量,它的初始值是weights的两倍
    w_twice = tf.Variable(weights.initialized_value() * 2.0, name="w_twice")
    
    使用变量
    v = tf.get_variable("v", shape=(), initializer=tf.zeros_initializer())
    w = v + 1
    
    ###为变量赋值
    v = tf.get_variable("v", shape=(), initializer=tf.zeros_initializer())
    assignment = v.assign_add(1)
    tf.global_variables_initializer().run()
    sess.run(assignment)  # or assignment.op.run(), or assignment.eval()
    
    v = tf.get_variable("v", shape=(), initializer=tf.zeros_initializer())
    assignment = v.assign_add(1)
    with tf.control_dependencies([assignment]):
        w = v.read_value() #w在assign_add操作后反映v的值
    
    共享变量
    ###创建一个卷积层
    def conv_relu(input, kernel_shape, bias_shape):
        # Create variable named "weights".
        weights = tf.get_variable("weights", kernel_shape,
            initializer=tf.random_normal_initializer())
        # Create variable named "biases".
        biases = tf.get_variable("biases", bias_shape,
            initializer=tf.constant_initializer(0.0))
        conv = tf.nn.conv2d(input, weights,
            strides=[1, 1, 1, 1], padding='SAME')
        return tf.nn.relu(conv + biases)
    
    ###由于期望的操作不清楚(创建新变量还是重新使用现有变量?),因此 TensorFlow 将会失败。
    input1 = tf.random_normal([1,10,10,32])
    input2 = tf.random_normal([1,20,20,32])
    x = conv_relu(input1, kernel_shape=[5, 5, 32, 32], bias_shape=[32])
    x = conv_relu(x, kernel_shape=[5, 5, 32, 32], bias_shape = [32])  # This fails.
    
    用变量域实现共享参数

    这里主要包括两个函数接口:`

    • tf.get_variable(<name>, <shape>, <initializer>) :根据指定的变量名实例化或返回一个 tensor 对象
    • tf.variable_scope(<scope_name>):管理 tf.get_variable() 变量的域名

    tf.get_variable() 的机制跟 tf.Variable() 有很大不同,如果指定的变量名已经存在(即先前已经用同一个变量名通过 get_variable() 函数实例化了变量),那么 get_variable()只会返回之前的变量,否则才创造新的变量。

    def conv_relu(input, kernel_shape, bias_shape):
        # Create variable named "weights".
        weights = tf.get_variable("weights", kernel_shape,
            initializer=tf.random_normal_initializer())
        # Create variable named "biases".
        biases = tf.get_variable("biases", bias_shape,
            initializer=tf.constant_initializer(0.0))
        conv = tf.nn.conv2d(input, weights,
            strides=[1, 1, 1, 1], padding='SAME')
        return tf.nn.relu(conv + biases)
    
    
    def my_image_filter(input_images):
        with tf.variable_scope("conv1"):
            # Variables created here will be named "conv1/weights", "conv1/biases".
            relu1 = conv_relu(input_images, [5, 5, 32, 32], [32])
        with tf.variable_scope("conv2"):
            # Variables created here will be named "conv2/weights", "conv2/biases".
            return conv_relu(relu1, [5, 5, 32, 32], [32])
    

    先定义一个 conv_relu() 函数,用 tf.variable_scope() 来分别处理两个卷积层的参数。正如注释中提到的那样,这个函数会在内部的变量名前面再加上一个「scope」前缀,比如:conv1/weights表示第一个卷积层的权值参数。这样一来,我们就可以通过域名来区分各个层之间的参数了。
    不过,如果直接这样调用 my_image_filter,是会抛异常的:

    result1 = my_image_filter(image1)
    result2 = my_image_filter(image2)
    # Raises ValueError(... conv1/weights already exists ...)
    

    因为 tf.get_variable()虽然可以共享变量,但默认上它只是检查变量名,防止重复。要开启变量共享,你还必须指定在哪个域名内可以共用变量:

    with tf.variable_scope("image_filters") as scope:
        result1 = my_image_filter(image1)
        scope.reuse_variables()
        result2 = my_image_filter(image2)
    

    到这一步,共享变量的工作就完成了。你甚至都不用在函数外定义变量,直接调用同一个函数并传入不同的域名,就可以让 TensorFlow 来帮你管理变量了。

    若部分变量共享,部分不共享:

    def test(mode):
        w = tf.get_variable(name=mode+"w", shape=[1,2])
        u = tf.get_variable(name="u", shape=[1,2])
        return w, u
    
    with tf.variable_scope("test", reuse=tf.AUTO_REUSE) as scope:
        w1, u1 = test("mode1")
        w2, u2 = test("mode2")
    

    这里只是加了一个参数 reuse=tf.AUTO_REUSE,但正如名字所示,这是一种自动共享的机制,当系统检测到我们用了一个之前已经定义的变量时,就开启共享,否则就重新创建变量。

    变量域的工作机理

    首先,TensorFlow 会判断是否要共享变量,也就是判断 tf.get_variable_scope().reuse 的值,如果结果为 False(即你没有在变量域内调用scope.reuse_variables()),那么 TensorFlow 认为你是要初始化一个新的变量,紧接着它会判断这个命名的变量是否存在。如果存在,会抛出 ValueError 异常,否则,就根据 initializer 初始化变量:

    with tf.variable_scope("foo"):
        v = tf.get_variable("v", [1])
    assert v.name == "foo/v:0"
    

    而如果 tf.get_variable_scope().reuse == True,那么 TensorFlow 会执行相反的动作,就是到程序里面寻找变量名为 scope name + name 的变量,如果变量不存在,会抛出 ValueError 异常,否则,就返回找到的变量:

    with tf.variable_scope("foo"):
        v = tf.get_variable("v", [1])
    with tf.variable_scope("foo", reuse=True):
        v1 = tf.get_variable("v", [1])
    assert v1 is v
    
    变量域的基本使用
    • 变量域可以嵌套使用
    with tf.variable_scope("foo"):
        with tf.variable_scope("bar"):
            v = tf.get_variable("v", [1])
    assert v.name == "foo/bar/v:0"
    

    我们也可以通过 tf.get_variable_scope() 来获得当前的变量域对象,并通过 reuse_variables() 方法来设置是否共享变量。不过,TensorFlow 并不支持将 reuse 值设为 False,如果你要停止共享变量,可以选择离开当前所在的变量域,或者再进入一个新的变量域(比如,再进入一个 with 语句,然后指定新的域名)。
    还需注意的一点是,一旦在一个变量域内将 reuse 设为 True,那么这个变量域的子变量域也会继承这个 reuse 值,自动开启共享变量:

    with tf.variable_scope("root"):
        # At start, the scope is not reusing.
        assert tf.get_variable_scope().reuse == False
        with tf.variable_scope("foo"):
            # Opened a sub-scope, still not reusing.
            assert tf.get_variable_scope().reuse == False
        with tf.variable_scope("foo", reuse=True):
            # Explicitly opened a reusing scope.
            assert tf.get_variable_scope().reuse == True
            with tf.variable_scope("bar"):
                # Now sub-scope inherits the reuse flag.
                assert tf.get_variable_scope().reuse == True
        # Exited the reusing scope, back to a non-reusing one.
        assert tf.get_variable_scope().reuse == False
    
    捕获变量域对象

    如果一直用字符串来区分变量域,写起来容易出错。为此,TensorFlow 提供了一个变量域对象来帮助我们管理代码:

    with tf.variable_scope("foo") as foo_scope:
        v = tf.get_variable("v", [1])
    with tf.variable_scope(foo_scope)
        w = tf.get_variable("w", [1])
    with tf.variable_scope(foo_scope, reuse=True)
        v1 = tf.get_variable("v", [1])
        w1 = tf.get_variable("w", [1])
    assert v1 is v
    assert w1 is w
    

    记住,用这个变量域对象还可以让我们跳出当前所在的变量域区域:

    with tf.variable_scope("foo") as foo_scope:
        assert foo_scope.name == "foo"
    with tf.variable_scope("bar")
        with tf.variable_scope("baz") as other_scope:
            assert other_scope.name == "bar/baz"
            with tf.variable_scope(foo_scope) as foo_scope2:
                assert foo_scope2.name == "foo"  # Not changed.
    
    在变量域内初始化变量

    每次初始化变量时都要传入一个 initializer,这实在是麻烦,而如果使用变量域的话,就可以批量初始化参数了:

    with tf.variable_scope("foo", initializer=tf.constant_initializer(0.4)):
        v = tf.get_variable("v", [1])
        assert v.eval() == 0.4  # Default initializer as set above.
        w = tf.get_variable("w", [1], initializer=tf.constant_initializer(0.3)):
        assert w.eval() == 0.3  # Specific initializer overrides the default.
        with tf.variable_scope("bar"):
            v = tf.get_variable("v", [1])
            assert v.eval() == 0.4  # Inherited default initializer.
        with tf.variable_scope("baz", initializer=tf.constant_initializer(0.2)):
            v = tf.get_variable("v", [1])
            assert v.eval() == 0.2  # Changed default initializer.
    

    TensorFlow 使用数据流图将计算表示为独立的指令之间的依赖关系。这可生成低级别的编程模型,在该模型中,您首先定义数据流图,然后创建 TensorFlow 会话,以便在一组本地和远程设备上运行图的各个部分。

    为什么使用数据流图

    计算图是排列成一个图的一系列TensorFlow指令。
    tf.Graph包含两类相关信息:

    • 图结构。由两种类型的对象组成:
      • 指令:图的节点。消耗和生成张量的计算。
      • 张量:图的边。代表流经图的值。
    • 图集合。
    构建tf.Graph

    tf.Graph 对象为其包含的 tf.Operation对象定义一个命名空间。TensorFlow 会自动为您的图中的每个指令选择一个唯一名称,但您也可以指定描述性名称,使您的程序阅读和调试起来更轻松。TensorFlow API 提供两种方法来改写指令的名称:

    • 每个创建新的 tf.Operation 或返回新的 tf.Tensor的 API 函数可以接受可选的 name参数。例如,tf.constant(42.0, name="answer") 创建一个名为 "answer" 的新 tf.Operation并返回一个名为 "answer:0" 的 tf.Tensor。如果默认图已包含名为 "answer"`的指令,则 TensorFlow 会在名称上附加 "_1"、"_2" 等字符,以便让名称具有唯一性。
    c_0 = tf.constant(0, name="c")  # => operation named "c"
    
    # Already-used names will be "uniquified".
    c_1 = tf.constant(2, name="c")  # => operation named "c_1"
    
    # Name scopes add a prefix to all operations created in the same context.
    with tf.name_scope("outer"):
      c_2 = tf.constant(2, name="c")  # => operation named "outer/c"
    
      # Name scopes nest like paths in a hierarchical file system.
      with tf.name_scope("inner"):
        c_3 = tf.constant(3, name="c")  # => operation named "outer/inner/c"
    
      # Exiting a name scope context will return to the previous prefix.
      c_4 = tf.constant(4, name="c")  # => operation named "outer/c_1"
    
      # Already-used name scopes will be "uniquified".
      with tf.name_scope("inner"):
        c_5 = tf.constant(5, name="c")  # => operation named "outer/inner_1/c"
    
    类似于张量的对象

    默认情况下,每次您使用同一个类似于张量的对象时,TensorFlow 将创建新的 tf.Tensor。如果类似于张量的对象很大(例如包含一组训练示例的 numpy.ndarray),且您多次使用该对象,您可能会用光内存。要避免出现此问题,请在类似于张量的对象:

    • tf.Tensor
    • tf.Variable
    • numpy.ndarray
    • list
    • 标量 Python 类型:bool、float、int、str
    tf.Session
    # Create a default in-process session.
    with tf.Session() as sess:
      # ...
    
    # Create a remote session.
    with tf.Session("grpc://example.org:2222"):
      # ...
    

    由于 tf.Session 拥有物理资源(例如 GPU 和网络连接),它通常用作上下文管理器(在 with代码块中),该管理器可在您退出代码块时自动关闭会话。您也可以在不使用with代码块的情况下创建会话,但应在完成会话时明确调用 tf.Session.close以便释放资源

    tf.Session.run

    tf.Session.run方法是一种用于运行 tf.Operation 或对 tf.Tensor求值的主要机制。您可以将一个或多个 tf.Operation或 tf.Tensor对象传递到 tf.Session.run,TensorFlow 将执行计算结果所需的指令。

     = tf.constant([[37.0, -23.0], [1.0, 4.0]])
    w = tf.Variable(tf.random_uniform([2, 2]))
    y = tf.matmul(x, w)
    output = tf.nn.softmax(y)
    init_op = w.initializer
    
    with tf.Session() as sess:
      # Run the initializer on `w`.
      sess.run(init_op)
    
      # Evaluate `output`. `sess.run(output)` will return a NumPy array containing
      # the result of the computation.
      print(sess.run(output))
    
      # Evaluate `y` and `output`. Note that `y` will only be computed once, and its
      # result used both to return `y_val` and as an input to the `tf.nn.softmax()`
      # op. Both `y_val` and `output_val` will be NumPy arrays.
      y_val, output_val = sess.run([y, output])
    

    tf.Session.run也可以视情况接受Feed字典

    # Define a placeholder that expects a vector of three floating-point values,
    # and a computation that depends on it.
    x = tf.placeholder(tf.float32, shape=[3])
    y = tf.square(x)
    
    with tf.Session() as sess:
      # Feeding a value changes the result that is returned when you evaluate `y`.
      print(sess.run(y, {x: [1.0, 2.0, 3.0]}))  # => "[1.0, 4.0, 9.0]"
      print(sess.run(y, {x: [0.0, 0.0, 5.0]}))  # => "[0.0, 0.0, 25.0]"
    
      # Raises `tf.errors.InvalidArgumentError`, because you must feed a value for
      # a `tf.placeholder()` when evaluating a tensor that depends on it.
      sess.run(y)
    
      # Raises `ValueError`, because the shape of `37.0` does not match the shape
      # of placeholder `x`.
      sess.run(y, {x: 37.0})
    
    使用多个图进行编程
    g_1 = tf.Graph()
    with g_1.as_default():
      # Operations created in this scope will be added to `g_1`.
      c = tf.constant("Node in g_1")
    
      # Sessions created in this scope will run operations from `g_1`.
      sess_1 = tf.Session()
    
    g_2 = tf.Graph()
    with g_2.as_default():
      # Operations created in this scope will be added to `g_2`.
      d = tf.constant("Node in g_2")
    
    # Alternatively, you can pass a graph when constructing a `tf.Session`:
    # `sess_2` will run operations from `g_2`.
    sess_2 = tf.Session(graph=g_2)
    
    assert c.graph is g_1
    assert sess_1.graph is g_1
    
    # Print all of the operations in the default graph.
    g = tf.get_default_graph()
    print(g.get_operations())
    

    保存和恢复变量

    保存变量
    # Create some variables.
    v1 = tf.get_variable("v1", shape=[3], initializer = tf.zeros_initializer)
    v2 = tf.get_variable("v2", shape=[5], initializer = tf.zeros_initializer)
    
    inc_v1 = v1.assign(v1+1)
    dec_v2 = v2.assign(v2-1)
    
    # Add an op to initialize the variables.
    init_op = tf.global_variables_initializer()
    
    # Add ops to save and restore all the variables.
    saver = tf.train.Saver()
    
    # Later, launch the model, initialize the variables, do some work, and save the
    # variables to disk.
    with tf.Session() as sess:
      sess.run(init_op)
      # Do some work with the model.
      inc_v1.op.run()
      dec_v2.op.run()
      # Save the variables to disk.
      save_path = saver.save(sess, "/tmp/model.ckpt")
      print("Model saved in path: %s" % save_path)
    
    恢复变量
    tf.reset_default_graph()
    
    # Create some variables.
    v1 = tf.get_variable("v1", shape=[3])
    v2 = tf.get_variable("v2", shape=[5])
    
    # Add ops to save and restore all the variables.
    saver = tf.train.Saver()
    
    # Later, launch the model, use the saver to restore variables from disk, and
    # do some work with the model.
    with tf.Session() as sess:
      # Restore variables from disk.
      saver.restore(sess, "/tmp/model.ckpt")
      print("Model restored.")
      # Check the values of the variables
      print("v1 : %s" % v1.eval())
      print("v2 : %s" % v2.eval())
    

    相关文章

      网友评论

          本文标题:TensorFlow学习笔记(1)——低级API

          本文链接:https://www.haomeiwen.com/subject/xkqmdftx.html