На этом шаге мы рассмотрим особенности использования этих тензоров.
В любых операциях, выполняемых с помощью TensorFlow, участвуют тензоры. Тензоры создаются с некоторыми начальными значениями. Например, можно создать тензор с единицами во всех элементах, с нулями (пример 3.1) или со случайными значениями (пример 3.2).
import tensorflow as tf # Эквивалентно вызову np.ones(shape=(2, 1)) x = tf.ones(shape=(2, 1)) print(x) tf.Tensor( [[1.] [1.]], shape=(2, 1), dtype=float32) # Эквивалентно вызову np.zeros(shape=(2, 1)) x = tf.zeros(shape=(2, 1)) print(x) tf.Tensor( [[0.] [0.]], shape=(2, 1), dtype=float32)
# Для создания тензора со случайными значениями используется # нормальное распределение со средним отклонением 0 и # стандартным отклонением 1. Эквивалентно вызову # np.random.normal(size=(3, 1), loc=0., scale=1.) x = tf.random.normal(shape=(3, 1), mean=0., stddev=1.) print(x) tf.Tensor( [[ 0.8433557 ] [-1.8125836 ] [ 0.69369423]], shape=(3, 1), dtype=float32) # Для создания тензора со случайными значениями # используется равномерное распределение между 0 и 1. # Эквивалентно вызову # np.random.uniform(size=(3, 1), low=0., high=1.) x = tf.random.uniform(shape=(3, 1), minval=0., maxval=1.) print(x) tf.Tensor( [[0.56918085] [0.5042844 ] [0.6338109 ]], shape=(3, 1), dtype=float32)
Существенная разница между массивами NumPy и тензорами TensorFlow заключается в том, что тензоры TensorFlow не могут изменяться, они подобны константам. Например, в NumPy можно выполнить следующие операции.
import numpy as np x = np.ones(shape=(2, 2)) x[0, 0] = 0.
Если попробовать сделать то же самое с тензором TensorFlow, библиотека сообщит об ошибке:
EagerTensor object does not support item assignment (Объект EagerTensor не поддерживает присваивание значений элементам).
# Эта операция потерпит неудачу, # потому что тензоры не могут изменяться x = tf.ones(shape=(2, 2)) x[0, 0] = 0.
Как вы знаете, чтобы обучить модель, нужно в цикле обновлять ее состояние, представленное набором тензоров. Но если тензоры нельзя изменять, как же тогда происходит обучение? В таком случае используются переменные. Для управления изменяемым состоянием в TensorFlow применяется класс tf.Variable. Вы уже видели его в реализации цикла обучения.
Чтобы создать такую переменную, нужно указать какое-то начальное значение, например случайный тензор
v = tf.Variable(initial_value=tf.random.normal(shape=(3, 1)))
print(v)
<tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[-0.5215308 ],
[-0.43471026],
[ 0.85999465]], dtype=float32)>
Состояние переменной можно менять с помощью ее метода assign(), как показано ниже.
v.assign(tf.ones((3, 1)))
print(v)
<tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=
array([[1.],
[1.],
[1.]], dtype=float32)>
Этот метод применим также к подмножеству элементов.
print(v[0, 0].assign(3.))
<tf.Variable 'UnreadVariable' shape=(3, 1) dtype=float32, numpy=
array([[3.],
[1.],
[1.]], dtype=float32)>
Аналогично для выполнения операций += и -= предлагаются методы assign_add() и assign_sub().
print(v.assign_add(tf.ones((3, 1))))
<tf.Variable 'UnreadVariable' shape=(3, 1) dtype=float32, numpy=
array([[4.],
[2.],
[2.]], dtype=float32)>
На следующем шаге мы рассмотрим операции с тензорами.