TensorFlow MatMul操作rank错误问题记录

2024-08-21 20:08

本文主要是介绍TensorFlow MatMul操作rank错误问题记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个问题应该算是很简单的,只不过我是新手,需要多记录下。在看Stanford的TensorFlow教程(地址为:https://www.youtube.com/watch?v=g-EvyKpZjmQ&list=PLQ0sVbIj3URf94DQtGPJV629ctn2c1zN-)Lecture 1的一段代码的时候,发现并不能运行:

import tensorflow as tfwith tf.device('/gpu:1'):a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], name='a')b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], name='b')c = tf.matmul(a, b)sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))print(sess.run(c))

报错为:ValueError: Shape must be rank 2 but is rank 1 for 'MatMul' (op: 'MatMul') with input shapes: [6], [6].

TensorFlow才接触不久,基本都是运行下别人的代码,看看效果,所以对其中的方法也都是混个脸熟,并不十分清楚。这里的tf.matmul()方法和另一个tf.mul()要区分下,tf.mul实际上在新版的TensorFlow中已经修改为tf.multiply()了,我是参考https://blog.csdn.net/liuyuemaicha/article/details/70305678这篇博文学习的,测试下multiply:

import tensorflow as tfa = tf.get_variable('a', [2, 3], initializer=tf.random_normal_initializer(mean=0, stddev=1))
b = tf.get_variable('b', [2, 3], initializer=tf.constant_initializer(2))
c = tf.get_variable('c', [3, 2], initializer=tf.ones_initializer())init_op = tf.global_variables_initializer()with tf.Session() as sess:sess.run(init_op)print('a:\n', sess.run(a))print('b:\n', sess.run(b))print('c:\n', sess.run(c))print('multiply a, b')print(sess.run(tf.multiply(a, b)))print('matmul a, c')print(sess.run(tf.matmul(a, c)))

tf.get_variable()方法的使用第一个参数是name,第二个是shape,第三个是initializer。tf.random_normal_initializer()方法就是返回一个具有正态分布的张量初始化器,均值(期望值)mean默认为0,标准差默认为1,也就是默认为标准正态分布。得到的结果为:

a:
 [[-1.2580129   0.42341614  0.2203044 ]
 [-1.1805797  -1.8744725  -0.1812443 ]]
b:
 [[2. 2. 2.]
 [2. 2. 2.]]
c:
 [[1. 1.]
 [1. 1.]
 [1. 1.]]
multiply a, b
[[-2.5160258  0.8468323  0.4406088]
 [-2.3611593 -3.748945  -0.3624886]]
matmul a, c
[[-0.6142924 -0.6142924]
 [-3.2362967 -3.2362967]]

可以看到tf.multiply()方法是对应位置元素直接相乘的,因此要求二者的shape相等,该操作也成为哈达马积(Hadamard)。a和c两个变量一个是2行3列,一个3行2列,可以用tf.matmul()方法求矩阵乘积,得到了2行2列的一个矩阵。

回到刚刚的问题,比如参考https://blog.csdn.net/blythe0107/article/details/74171870,可以采用reshape的方式,使前者的列等于后者的行也就行了,如下:

import tensorflow as tf
import numpy as npwith tf.device('/gpu:0'):a = tf.constant(np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]).reshape(2, 3), name='a')b = tf.constant(np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]).reshape(3, 2), name='b')c = tf.matmul(a, b)with tf.device('/gpu:1'):d = tf.constant(np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]).reshape(2, 3), name='d')e = tf.constant(np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]).reshape(3, 2), name='e')f = tf.matmul(d, e)sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))print(sess.run(c))
print(sess.run(f))

这样得到的输出如下:

2018-08-02 15:52:42.801535: I tensorflow/core/common_runtime/gpu/gpu_device.cc:971] 1:   Y N
2018-08-02 15:52:42.801871: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1084] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 10388 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1080 Ti, pci bus id: 0000:21:00.0, compute capability: 6.1)
2018-08-02 15:52:42.905229: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1084] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:1 with 10407 MB memory) -> physical GPU (device: 1, name: GeForce GTX 1080 Ti, pci bus id: 0000:2d:00.0, compute capability: 6.1)
Device mapping:
/job:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: GeForce GTX 1080 Ti, pci bus id: 0000:21:00.0, compute capability: 6.1
/job:localhost/replica:0/task:0/device:GPU:1 -> device: 1, name: GeForce GTX 1080 Ti, pci bus id: 0000:2d:00.0, compute capability: 6.1
2018-08-02 15:52:43.010702: I tensorflow/core/common_runtime/direct_session.cc:288] Device mapping:
/job:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: GeForce GTX 1080 Ti, pci bus id: 0000:21:00.0, compute capability: 6.1
/job:localhost/replica:0/task:0/device:GPU:1 -> device: 1, name: GeForce GTX 1080 Ti, pci bus id: 0000:2d:00.0, compute capability: 6.1

MatMul: (MatMul): /job:localhost/replica:0/task:0/device:GPU:0
2018-08-02 15:52:43.011677: I tensorflow/core/common_runtime/placer.cc:886] MatMul: (MatMul)/job:localhost/replica:0/task:0/device:GPU:0
MatMul_1: (MatMul): /job:localhost/replica:0/task:0/device:GPU:1
2018-08-02 15:52:43.011720: I tensorflow/core/common_runtime/placer.cc:886] MatMul_1: (MatMul)/job:localhost/replica:0/task:0/device:GPU:1
a: (Const): /job:localhost/replica:0/task:0/device:GPU:0
2018-08-02 15:52:43.011741: I tensorflow/core/common_runtime/placer.cc:886] a: (Const)/job:localhost/replica:0/task:0/device:GPU:0
b: (Const): /job:localhost/replica:0/task:0/device:GPU:0
2018-08-02 15:52:43.011760: I tensorflow/core/common_runtime/placer.cc:886] b: (Const)/job:localhost/replica:0/task:0/device:GPU:0
d: (Const): /job:localhost/replica:0/task:0/device:GPU:1
2018-08-02 15:52:43.011778: I tensorflow/core/common_runtime/placer.cc:886] d: (Const)/job:localhost/replica:0/task:0/device:GPU:1
e: (Const): /job:localhost/replica:0/task:0/device:GPU:1
2018-08-02 15:52:43.011795: I tensorflow/core/common_runtime/placer.cc:886] e: (Const)/job:localhost/replica:0/task:0/device:GPU:1
[[22. 28.]
 [49. 64.]]
[[22. 28.]
 [49. 64.]]

可以看到,变量和op可以指定GPU,本例中a和b用了GPU0,另外也处理了matmul()的操作。而d和e即计算f的任务则放在了GPU1上,这个可能算是最简单了单主机多GPU使用了。

关于前面的变量使用,记录如下。

TensorFlow有两个关于variable的op,即tf.Variable()和tf.get_variable(),这里参考

https://blog.csdn.net/u012436149/article/details/53696970/学习下。比如下面的代码:

import tensorflow as tfw_1 = tf.Variable(3, name='w_1')
w_2 = tf.Variable(1, name='w_1')print(w_1.name)
print(w_2.name)init_op = tf.global_variables_initializer()with tf.Session() as sess:sess.run(init_op)sess.run(tf.Print(w_1, [w_1, w_1.name, str(w_1.value)]))sess.run(tf.Print(w_2, [w_2, w_2.name, str(w_2.value)]))

这里使用了tf.Print()方法来输出一些调试信息,其value部分用str()方法处理下不然报错。输出结果:

w_1:0
w_1_1:0

[3][w_1:0][<bound method Variable.value of <tf.Variable \'w_1:0\' shape=() dtype=int32_ref>>]
[1][w_1_1:0][<bound method Variable.value of <tf.Variable \'w_1_1:0\' shape=() dtype=int32_ref>>]

使用tf.Variable()系统会自动处理命名冲突,这里如果用tf.get_variable()则会报错w_1变量已存在。所以当我们需要共享变量的时候,用tf.get_variable()。关于其实质区别,看下这段代码:

import tensorflow as tfwith tf.variable_scope('scope1'):w1 = tf.get_variable('w1', shape=[])w2 = tf.Variable(0.0, name='w_1')with tf.variable_scope('scope1', reuse=True):w1_p = tf.get_variable('w1', shape=[])w2_p = tf.Variable(1.0, name='w2')print(w1 is w1_p, w2 is w2_p)

输出为True False。由于tf.Variable()每次都在创建新对象,所有reuse=True 和它并没有什么关系。对于get_variable(),如果已经创建的变量对象,就把那个对象返回,如果没有创建变量对象的话,就创建一个新的。

 

这篇关于TensorFlow MatMul操作rank错误问题记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1094153

相关文章

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

在Spring Boot中集成RabbitMQ的实战记录

《在SpringBoot中集成RabbitMQ的实战记录》本文介绍SpringBoot集成RabbitMQ的步骤,涵盖配置连接、消息发送与接收,并对比两种定义Exchange与队列的方式:手动声明(... 目录前言准备工作1. 安装 RabbitMQ2. 消息发送者(Producer)配置1. 创建 Spr

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

Springboot如何正确使用AOP问题

《Springboot如何正确使用AOP问题》:本文主要介绍Springboot如何正确使用AOP问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录​一、AOP概念二、切点表达式​execution表达式案例三、AOP通知四、springboot中使用AOP导出