In [0]:
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
In [0]:
from __future__ import print_function
import tensorflow as tf
try:
tf.contrib.eager.enable_eager_execution()
print("TF imported with eager execution!")
except ValueError:
print("TF already imported with eager execution!")
您可以对张量执行很多典型数学运算 (TF API)。以下代码会创建下列矢量(一维张量),所有矢量都正好有六个元素:
primes
矢量。1
的 ones
矢量。primes
矢量中的元素翻倍而创建的矢量。
In [0]:
primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)
print("primes:", primes
)
ones = tf.ones([6], dtype=tf.int32)
print("ones:", ones)
just_beyond_primes = tf.add(primes, ones)
print("just_beyond_primes:", just_beyond_primes)
twos = tf.constant([2, 2, 2, 2, 2, 2], dtype=tf.int32)
primes_doubled = primes * twos
print("primes_doubled:", primes_doubled)
输出张量不仅会返回其值,还会返回其形状(将在下一部分中讨论)以及存储在张量中的值的类型。调用张量的 numpy
方法会返回该张量的值(以 NumPy 数组形式):
In [0]:
some_matrix = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.int32)
print(some_matrix)
print("\nvalue of some_matrix is:\n", some_matrix.numpy())
形状用于描述张量维度的大小和数量。张量的形状表示为 list
,其中第 i
个元素表示维度 i
的大小。列表的长度表示张量的阶(即维数)。
有关详情,请参阅 TensorFlow 文档。
以下是一些基本示例:
In [0]:
# A scalar (0-D tensor).
scalar = tf.zeros([])
# A vector with 3 elements.
vector = tf.zeros([3])
# A matrix with 2 rows and 3 columns.
matrix = tf.zeros([2, 3])
print('scalar has shape', scalar.get_shape(), 'and value:\n', scalar.numpy())
print('vector has shape', vector.get_shape(), 'and value:\n', vector.numpy())
print('matrix has shape', matrix.get_shape(), 'and value:\n', matrix.numpy())
在数学中,您只能对形状相同的张量执行元素级运算(例如,相加和等于)。不过,在 TensorFlow 中,您可以对张量执行传统意义上不可行的运算。TensorFlow 支持广播(一种借鉴自 NumPy 的概念)。利用广播,元素级运算中的较小数组会增大到与较大数组具有相同的形状。例如,通过广播:
[6]
的张量,则大小为 [1]
或 []
的张量可以作为运算数。[4, 6]
的张量,则以下任何大小的张量都可以作为运算数:[1, 6]
[6]
[]
如果运算需要大小为 [3, 5, 6]
的张量,则以下任何大小的张量都可以作为运算数:
[1, 5, 6]
[3, 1, 6]
[3, 5, 1]
[1, 1, 1]
[5, 6]
[1, 6]
[6]
[1]
[]
注意:当张量被广播时,从概念上来说,系统会复制其条目(出于性能考虑,实际并不复制。广播专为实现性能优化而设计)。
有关完整的广播规则集,请参阅简单易懂的 NumPy 广播文档。
以下代码执行了与之前一样的张量运算,不过使用的是标量值(而不是全包含 1
或全包含 2
的矢量)和广播。
In [0]:
primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)
print("primes:", primes)
one = tf.constant(1, dtype=tf.int32)
print("one:", one)
just_beyond_primes = tf.add(primes, one)
print("just_beyond_primes:", just_beyond_primes)
two = tf.constant(2, dtype=tf.int32)
primes_doubled = primes * two
print("primes_doubled:", primes_doubled)
In [0]:
# Write your code for Task 1 here.
In [0]:
# Task: Square each element in the primes vector, then subtract 1.
def solution(primes):
primes_squared = tf.multiply(primes, primes)
neg_one = tf.constant(-1, dtype=tf.int32)
just_under_primes_squared = tf.add(primes_squared, neg_one)
return just_under_primes_squared
def alternative_solution(primes):
primes_squared = tf.pow(primes, 2)
one = tf.constant(1, dtype=tf.int32)
just_under_primes_squared = tf.subtract(primes_squared, one)
return just_under_primes_squared
primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)
just_under_primes_squared = solution(primes)
print("just_under_primes_squared:", just_under_primes_squared)
In [0]:
# A 3x4 matrix (2-d tensor).
x = tf.constant([[5, 2, 4, 3], [5, 1, 6, -2], [-1, 3, -1, -2]],
dtype=tf.int32)
# A 4x2 matrix (2-d tensor).
y = tf.constant([[2, 2], [3, 5], [4, 5], [1, 6]], dtype=tf.int32)
# Multiply `x` by `y`; result is 3x2 matrix.
matrix_multiply_result = tf.matmul(x, y)
print(matrix_multiply_result)
In [0]:
# Create an 8x2 matrix (2-D tensor).
matrix = tf.constant(
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14], [15, 16]],
dtype=tf.int32)
reshaped_2x8_matrix = tf.reshape(matrix, [2, 8])
reshaped_4x4_matrix = tf.reshape(matrix, [4, 4])
print("Original matrix (8x2):")
print(matrix.numpy())
print("Reshaped matrix (2x8):")
print(reshaped_2x8_matrix.numpy())
print("Reshaped matrix (4x4):")
print(reshaped_4x4_matrix.numpy())
此外,您还可以使用 tf.reshape
更改张量的维数(“阶”)。
例如,您可以将 8x2 张量变形为三维 2x2x4 张量或一维 16 元素张量。
In [0]:
# Create an 8x2 matrix (2-D tensor).
matrix = tf.constant(
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14], [15, 16]],
dtype=tf.int32)
reshaped_2x2x4_tensor = tf.reshape(matrix, [2, 2, 4])
one_dimensional_vector = tf.reshape(matrix, [16])
print("Original matrix (8x2):")
print(matrix.numpy())
print("Reshaped 3-D tensor (2x2x4):")
print(reshaped_2x2x4_tensor.numpy())
print("1-D vector:")
print(one_dimensional_vector.numpy())
In [0]:
# Write your code for Task 2 here.
请注意,当两个矩阵相乘时,第一个矩阵的列数必须等于第二个矩阵的行数。
一个可行的解决方案是,将 a
变形为 2x3 矩阵,并将 b
变形为 3x1 矩阵,从而在相乘后得到一个 2x1 矩阵:
In [0]:
# Task: Reshape two tensors in order to multiply them
a = tf.constant([5, 3, 2, 7, 1, 4])
b = tf.constant([4, 6, 3])
reshaped_a = tf.reshape(a, [2, 3])
reshaped_b = tf.reshape(b, [3, 1])
c = tf.matmul(reshaped_a, reshaped_b)
print("reshaped_a (2x3):")
print(reshaped_a.numpy())
print("reshaped_b (3x1):")
print(reshaped_b.numpy())
print("reshaped_a x reshaped_b (2x1):")
print(c.numpy())
还有一个解决方案是,将 a
变形为 6x1 矩阵,并将 b
变形为 1x3 矩阵,从而在相乘后得到一个 6x3 矩阵。
In [0]:
# Create a scalar variable with the initial value 3.
v = tf.contrib.eager.Variable([3])
# Create a vector variable of shape [1, 4], with random initial values,
# sampled from a normal distribution with mean 1 and standard deviation 0.35.
w = tf.contrib.eager.Variable(tf.random_normal([1, 4], mean=1.0, stddev=0.35))
print("v:", v.numpy())
print("w:", w.numpy())
要更改变量的值,请使用 assign
操作:
In [0]:
v = tf.contrib.eager.Variable([3])
print(v.numpy())
tf.assign(v, [7])
print(v.numpy())
v.assign([5])
print(v.numpy())
向变量赋予新值时,其形状必须和之前的形状一致:
In [0]:
v = tf.contrib.eager.Variable([[1, 2, 3], [4, 5, 6]])
print(v.numpy())
try:
print("Assigning [7, 8, 9] to v")
v.assign([7, 8, 9])
except ValueError as e:
print("Exception:", e)
还有很多关于变量的内容我们并未在这里提及,例如加载和存储。要了解详情,请参阅 TensorFlow 文档。
创建一个骰子模拟,在模拟中生成一个 10x3
二维张量,其中:
1
和 2
均存储一个六面骰子(值为 1-6)的一次投掷值。3
存储同一行中列 1
和 2
的值的总和。例如,第一行中可能会包含以下值:
1
存储 4
2
存储 3
3
存储 7
要完成此任务,您需要浏览 TensorFlow 文档。
In [0]:
# Write your code for Task 3 here.
我们将投掷骰子得到的值分别放入两个 10x1 矩阵中,即 die1
和 die2
。两次投掷骰子得到的值的总和将存储在 dice_sum
中,然后,将三个 10x1 矩阵连接成一个矩阵,从而创建一个 10x3 矩阵。
或者,我们可以将投掷骰子得到的值放入一个 10x2 矩阵中,但将同一矩阵的不同列相加会更加复杂。我们还可以将投掷骰子得到的值放入两个一维张量(矢量)中,但这样做需要转置结果。
In [0]:
# Task: Simulate 10 throws of two dice. Store the results in a 10x3 matrix.
die1 = tf.contrib.eager.Variable(
tf.random_uniform([10, 1], minval=1, maxval=7, dtype=tf.int32))
die2 = tf.contrib.eager.Variable(
tf.random_uniform([10, 1], minval=1, maxval=7, dtype=tf.int32))
dice_sum = tf.add(die1, die2)
resulting_matrix = tf.concat(values=[die1, die2, dice_sum], axis=1)
print(resulting_matrix.numpy())