Основи на TensorFlow: Тензор, форма, тип, сесии и Operaтори

Какво е тензор?

Името на Tensorflow произлиза директно от неговата основна рамка: Tensor. В Tensorflow всички изчисления включват тензори. Тензорът е вектор или матрица от n-измерения, която представя всички видове данни. Всички стойности в тензор съдържат идентичен тип данни с известна (или частично известна) форма. Формата на данните е размерността на матрицата или масива.

Тензорът може да произхожда от входните данни или резултат от изчисление. В TensorFlow всички операции се извършват вътре в графика. Графиката е набор от изчисления, които се извършват последователно. Всяка операция се нарича операционен възел и е свързана една с друга.

Графиката очертава операциите и връзките между възлите. Въпреки това не показва стойностите. Ръбът на възлите е тензорът, т.е. начин за попълване на операцията с данни.

В машинното обучение моделите се захранват със списък от обекти, наречени вектори на характеристики. Векторът на характеристиките може да бъде от всякакъв тип данни. Векторът на характеристиките обикновено ще бъде основният вход за попълване на тензор. Тези стойности ще се влеят в операционен възел през тензора и резултатът от тази операция/изчисление ще създаде нов тензор, който от своя страна ще бъде използван в нова операция. Всички тези операции могат да се видят в графиката.

Представяне на тензор

В TensorFlow тензорът е колекция от характерни вектори (т.е. масив) от n-измерения. Например, ако имаме матрица 2×3 със стойности от 1 до 6, пишем:

Представяне на тензор
Представяне на тензор

TensorFlow представя тази матрица като:

[[1, 2, 3], 
   [4, 5, 6]]

Ако създадем триизмерна матрица със стойности от 1 до 8, имаме:

Представяне на тензор

TensorFlow представя тази матрица като:

[ [[1, 2],  
       [[3, 4],  
       [[5, 6],  
       [[7,8] ]

Забележка: Тензорът може да бъде представен със скалар или може да има форма с повече от три измерения. Просто е по-сложно да се визуализира по-високо ниво на измерение.

Видове тензор

В TensorFlow всички изчисления преминават през един или повече тензори. tf.tensor е обект с три свойства:

  • Уникален етикет (име)
  • Измерение (форма)
  • Тип данни (dtype)

Всяка операция, която ще извършвате с TensorFlow, включва манипулиране на тензор. Има четири основни типа тензор, които можете да създадете:

  • tf.Променлива
  • tf.константа
  • tf.placeholder
  • tf.SparseTensor

В този урок ще научите как да създадете tf.constant и tf.Variable.

Преди да преминем през урока, уверете се, че активирате conda средата с TensorFlow. Нарекохме тази среда hello-tf.

За потребител на MacOS:

source activate hello-tf

За Windows потребител:

activate hello-tf

След като направите това, вие сте готови да импортирате tensorflow

# Import tf
import tensorflow as tf

Създайте тензор с n-мерност

Започвате със създаването на тензор с едно измерение, а именно скалар.

За да създадете тензор, можете да използвате tf.constant(), както е показано в примера за форма на тензор TensorFlow по-долу:

tf.constant(value, dtype, name = "")
arguments

- `value`: Value of n dimension to define the tensor. Optional
- `dtype`: Define the type of data:    
    - `tf.string`: String variable    
    - `tf.float32`: Float variable    
    - `tf.int16`: Integer variable
- "name": Name of the tensor. Optional. By default, `Const_1:0`

За да създадете тензор с размерност 0, изпълнете следния код

## rank 0
# Default name
r1 = tf.constant(1, tf.int16) 
print(r1)			

Продукция

Tensor("Const:0", shape=(), dtype=int16)

Създайте тензор на n-измерение

# Named my_scalar
r2 = tf.constant(1, tf.int16, name = "my_scalar") 
print(r2)

Продукция

Tensor("my_scalar:0", shape=(), dtype=int16)

Всеки тензор се показва с името на тензора. Всеки тензорен обект се дефинира с тензорни атрибути като уникален етикет (име), измерение (форма) и типове данни TensorFlow (dtype).

Можете да дефинирате тензор с десетични стойности или с низ, като промените типа на данните.

# Decimal
r1_decimal = tf.constant(1.12345, tf.float32)
print(r1_decimal)
# String
r1_string = tf.constant("Guru99", tf.string)
print(r1_string)

Продукция

Tensor("Const_1:0", shape=(), dtype=float32)
Tensor("Const_2:0", shape=(), dtype=string)

Тензор с размерност 1 може да бъде създаден, както следва:

## Rank 1r1_vector = tf.constant([1,3,5], tf.int16)
print(r1_vector)
r2_boolean = tf.constant([True, True, False], tf.bool)
print(r2_boolean)

Продукция

Tensor("Const_3:0", shape=(3,), dtype=int16)
Tensor("Const_4:0", shape=(3,), dtype=bool)

Можете да забележите, че формата TensorFlow се състои само от 1 колона.

За да създадете масив от 2 тензорни измерения, трябва да затворите скобите след всеки ред. Вижте примера за формата на Keras Tensor по-долу

## Rank 2
r2_matrix = tf.constant([ [1, 2],
                          [3, 4] ],tf.int16)
print(r2_matrix)

Продукция

Tensor("Const_5:0", shape=(2, 2), dtype=int16)

Матрицата има 2 реда и 2 колони, попълнени със стойности 1, 2, 3, 4.

Матрица с 3 измерения се конструира чрез добавяне на още едно ниво със скобите.

## Rank 3
r3_matrix = tf.constant([ [[1, 2],
                           [3, 4], 
                           [5, 6]] ], tf.int16)
print(r3_matrix)

Продукция

Tensor("Const_6:0", shape=(1, 3, 2), dtype=int16)

Матрицата изглежда като на втората снимка.

Форма на тензора

Когато отпечатвате тензор, TensorFlow отгатва формата. Можете обаче да получите формата на тензора със свойството форма TensorFlow.

По-долу конструирате матрица, пълна с число от 10 до 15, и проверявате формата на m_shape

# Shape of tensor
m_shape = tf.constant([ [10, 11],
                        [12, 13],
                        [14, 15] ]                      
                     ) 
m_shape.shape

Продукция

TensorShape([Dimension(3), Dimension(2)])

Матрицата има 3 реда и 2 колони.

TensorFlow има полезни команди за създаване на вектор или матрица, запълнена с 0 или 1. Например, ако искате да създадете 1-D тензор със специфична форма 10, запълнена с 0, можете да изпълните кода по-долу:

# Create a vector of 0
print(tf.zeros(10))

Продукция

Tensor("zeros:0", shape=(10,), dtype=float32)

Свойството работи и за матрица. Тук създавате матрица 10×10, пълна с 1

# Create a vector of 1
print(tf.ones([10, 10]))

Продукция

Tensor("ones:0", shape=(10, 10), dtype=float32)

Можете да използвате формата на дадена матрица, за да направите вектор от единици. Матрицата m_shape е 3×2 измерения. Можете да създадете тензор с 3 реда, запълнени с един със следния код:

# Create a vector of ones with the same number of rows as m_shape
print(tf.ones(m_shape.shape[0]))

Продукция

Tensor("ones_1:0", shape=(3,), dtype=float32)

Ако подадете стойност 1 в скобата, можете да конструирате вектор от единици, равен на броя на колоните в матрицата m_shape.

# Create a vector of ones with the same number of column as m_shape
print(tf.ones(m_shape.shape[1]))

Продукция

Tensor("ones_2:0", shape=(2,), dtype=float32)

И накрая, можете да създадете матрица 3×2 само с единични

print(tf.ones(m_shape.shape))

Продукция

Tensor("ones_3:0", shape=(3, 2), dtype=float32)

Тип данни

Второто свойство на тензора е типът на данните. Тензорът може да има само един тип данни в даден момент. Един тензор може да има само един тип данни. Можете да върнете типа със свойството dtype.

print(m_shape.dtype)

Продукция

<dtype: 'int32'>

В някои случаи искате да промените типа на данните. В TensorFlow е възможно с метода tf.cast.

Пример

По-долу, тензорът с плаваща задна точка се преобразува в цяло число, като използвате метода cast.

# Change type of data
type_float = tf.constant(3.123456789, tf.float32)
type_int = tf.cast(type_float, dtype=tf.int32)
print(type_float.dtype)
print(type_int.dtype)

Продукция

<dtype: 'float32'>
<dtype: 'int32'>

TensorFlow избира типа данни автоматично, когато аргументът не е посочен по време на създаването на тензора. TensorFlow ще познае кои са най-вероятните типове данни. Например, ако подадете текст, той ще познае, че е низ и ще го преобразува в низ.

Създаване на оператор

Някои полезни оператори TensorFlow

Знаете как да създадете тензор с TensorFlow. Време е да се научите да извършвате математически операции.

TensorFlow съдържа всички основни операции. Можете да започнете с един прост. Ще използвате метода TensorFlow, за да изчислите квадрата на число. Тази операция е проста, защото е необходим само един аргумент за конструиране на тензора.

Квадратът на число се конструира с tf.sqrt(x) с x като плаващо число.

x = tf.constant([2.0], dtype = tf.float32)
print(tf.sqrt(x))

Продукция

Tensor("Sqrt:0", shape=(1,), dtype=float32)

Забележка: Изходът върна обект на тензор, а не резултат от квадрат на 2. В примера отпечатвате дефиницията на тензора, а не действителната оценка на операцията. В следващия раздел ще научите как TensorFlow работи за изпълнение на операциите.

Следва списък с често използвани операции. Идеята е същата. Всяка операция изисква един или повече аргументи.

  • tf.add(a, b)
  • tf.substract(a, b)
  • tf.multiply(a, b)
  • tf.div(a, b)
  • tf.pow(a, b)
  • tf.exp(a)
  • tf.sqrt(a)

Пример

# Add
tensor_a = tf.constant([[1,2]], dtype = tf.int32)
tensor_b = tf.constant([[3, 4]], dtype = tf.int32)

tensor_add = tf.add(tensor_a, tensor_b)print(tensor_add)

Продукция

Tensor("Add:0", shape=(1, 2), dtype=int32)

Обяснение на кода

Създайте два тензора:

  • един тензор с 1 и 2
  • един тензор с 3 и 4

Събирате двата тензора.

Забележете: че и двата тензора трябва да имат еднаква форма. Можете да извършите умножение върху двата тензора.

# Multiply
tensor_multiply = tf.multiply(tensor_a, tensor_b)
print(tensor_multiply)

Продукция

Tensor("Mul:0", shape=(1, 2), dtype=int32)

Променливи

Досега сте създали само постоянни тензори. Не е от голяма полза. Данните винаги пристигат с различни стойности, за да уловите това, можете да използвате класа Variable. Той ще представлява възел, където стойностите винаги се променят.

За да създадете променлива, можете да използвате метода tf.get_variable().

tf.get_variable(name = "", values, dtype, initializer)
argument
- `name = ""`: Name of the variable
- `values`: Dimension of the tensor
- `dtype`: Type of data. Optional
- `initializer`: How to initialize the tensor. Optional
If initializer is specified, there is no need to include the `values` as the shape of `initializer` is used.

Например кодът по-долу създава двуизмерна променлива с две произволни стойности. По подразбиране TensorFlow връща произволна стойност. Наименувате променливата var

# Create a Variable
## Create 2 Randomized values
var = tf.get_variable("var", [1, 2])
print(var.shape)

Продукция

(1, 2)

Във втория пример създавате променлива с един ред и две колони. Трябва да използвате [1,2], за да създадете измерението на променливата

Началните стойности на този тензор са нула. Например, когато обучавате модел, трябва да имате начални стойности, за да изчислите теглото на функциите. По-долу задавате тези първоначални стойности на нула.

var_init_1 = tf.get_variable("var_init_1", [1, 2], dtype=tf.int32,  initializer=tf.zeros_initializer)
print(var_init_1.shape)

Продукция

(1, 2)

Можете да предавате стойностите на постоянен тензор в променлива. Създавате постоянен тензор с метода tf.constant(). Използвате този тензор, за да инициализирате променливата.

Първите стойности на променливата са 10, 20, 30 и 40. Новият тензор ще има форма 2×2.

# Create a 2x2 matrixtensor_const = tf.constant([[10, 20],
[30, 40]])
# Initialize the first value of the tensor equals to tensor_const
var_init_2 = tf.get_variable("var_init_2", dtype=tf.int32,  initializer=tensor_const)
print(var_init_2.shape)

Продукция

(2, 2)

Заместител

Заместителят има за цел да захранва тензора. Заместителят се използва за инициализиране на данните, за да текат вътре в тензорите. За да предоставите заместител, трябва да използвате метода feed_dict. Заместителят ще бъде подаван само в рамките на сесия.

В следващия пример ще видите как да създадете контейнер с метода tf.placeholder. В следващата сесия ще се научите да захранвате контейнер с действителна тензорна стойност.

Синтаксисът е:

tf.placeholder(dtype,shape=None,name=None )
arguments:
- `dtype`: Type of data
- `shape`: dimension of the placeholder. Optional. By default, shape of the data
- `name`: Name of the placeholder. Optional			
data_placeholder_a = tf.placeholder(tf.float32, name = "data_placeholder_a")
print(data_placeholder_a)

Продукция

Tensor("data_placeholder_a:0", dtype=float32)

Сесия

TensorFlow работи около 3 основни компонента:

  • Крива
  • Тензор
  • Сесия
Компоненти Описание
Крива Графиката е фундаментална в TensorFlow. Всички математически операции (ops) се извършват вътре в графика. Можете да си представите графика като проект, в който се извършват всички операции. Възлите представляват тези операции, те могат да абсорбират или създават нови тензори.
Тензор Тензорът представлява данните, които преминават между операциите. Видяхте преди това как да инициализирате тензор. Разликата между константа и променлива е, че първоначалните стойности на променлива ще се променят с времето.
Сесия Сесия ще изпълни операцията от графиката. За да захранвате графиката със стойностите на тензор, трябва да отворите сесия. В рамките на сесия трябва да изпълните оператор, за да създадете изход.

Графиките и сесиите са независими. Можете да стартирате сесия и да получите стойностите, които да използвате по-късно за по-нататъшни изчисления.

В примера по-долу ще:

  • Създайте два тензора
  • Създайте операция
  • Отворете сесия
  • Отпечатайте резултата

Стъпка 1) Създавате два тензора x и y

## Create, run  and evaluate a session
x = tf.constant([2])
y = tf.constant([4])

Стъпка 2) Създавате оператора, като умножавате x и y

## Create operator
multiply = tf.multiply(x, y)

Стъпка 3) Отваряте сесия. Всички изчисления ще се извършват в рамките на сесията. Когато сте готови, трябва да затворите сесията.

## Create a session to run the code
sess = tf.Session()result_1 = sess.run(multiply)
print(result_1)
sess.close()

Продукция

[8]

Обяснение на кода

  • tf.Session(): Отваряне на сесия. Всички операции ще протичат в рамките на сесиите
  • run(multiply): изпълнете операцията, създадена в стъпка 2.
  • print(result_1): Накрая можете да отпечатате резултата
  • close(): Затворете сесията

Резултатът показва 8, което е умножението на x и y.

Друг начин за създаване на сесия е вътре в блок. Предимството е, че автоматично затваря сесията.

with tf.Session() as sess:    
result_2 = multiply.eval()
print(result_2)

Продукция

[8]

В контекста на сесията можете да използвате метода eval(), за да изпълните операцията. Това е еквивалентно на run(). Това прави кода по-четлив.

Можете да създадете сесия и да видите стойностите в тензорите, които сте създали досега.

## Check the tensors created before
sess = tf.Session()
print(sess.run(r1))
print(sess.run(r2_matrix))
print(sess.run(r3_matrix))

Продукция

1
[[1 2] 
 [3 4]]
[[[1 2]  
  [3 4]  
  [5 6]]]

Променливите са празни по подразбиране, дори след като създадете тензор. Трябва да инициализирате променливата, ако искате да използвате променливата. Обектът tf.global_variables_initializer() трябва да бъде извикан, за да инициализира стойностите на променлива. Този обект изрично ще инициализира всички променливи. Това е полезно, преди да обучите модел.

Можете да проверите стойностите на променливите, които сте създали преди. Имайте предвид, че трябва да използвате run, за да оцените тензора

sess.run(tf.global_variables_initializer())
print(sess.run(var))
print(sess.run(var_init_1))
print(sess.run(var_init_2))

Продукция

[[-0.05356491  0.75867283]]
[[0 0]]
[[10 20] 
 [30 40]]

Можете да използвате контейнера, който сте създали преди, и да го захранвате с действителна стойност. Трябва да предадете данните в метода feed_dict.

Например ще вземете силата на 2 от контейнера data_placeholder_a.

import numpy as np
power_a = tf.pow(data_placeholder_a, 2)
with tf.Session() as sess:  
data = np.random.rand(1, 10)  
print(sess.run(power_a, feed_dict={data_placeholder_a: data}))  # Will succeed.

Обяснение на кода

  • импортиране на numpy като np: Импортиране библиотека numpy за създаване на данните
  • tf.pow(data_placeholder_a, 2): Създайте ops
  • np.random.rand(1, 10): Създайте произволен масив от данни
  • feed_dict={data_placeholder_a: data}: Захранете контейнера с данни

Продукция

[[0.05478134 0.27213147 0.8803037  0.0398424  0.21172127 0.01444725  0.02584014 0.3763949  0.66022706 0.7565559 ]]

Крива

TensorFlow зависи от гениалния подход за изобразяване на операцията. Всички изчисления са представени със схема на поток от данни. Графиката на потока от данни е разработена, за да се видят зависимостите на данните между отделните операции. Математическата формула или алгоритъмът се състои от редица последователни операции. Графиката е удобен начин да визуализирате как са координирани изчисленията.

Графиката показва a възел и ръб. Възелът е представянето на операция, т.е. единицата за изчисление. Ръбът е тензорът, той може да произведе нов тензор или да консумира входните данни. Зависи от зависимостите между отделните операции.

Структурата на графиката свързва заедно операциите (т.е. възлите) и начина, по който тези операции се подават. Имайте предвид, че графиката не показва резултата от операциите, тя само помага да се визуализира връзката между отделните операции.

Да видим един пример.

Представете си, че искате да оцените следната функция:

Крива

TensorFlow ще създаде графика за изпълнение на функцията. Графиката изглежда така:

Пример за графика на TensorFlow

Пример за графика на TensorFlow

Можете лесно да видите пътя, по който тензорите ще стигнат до крайната дестинация.

Например можете да видите, че операцията добавяне не може да се извърши преди и . Графиката обяснява, че ще:

  1. изчисли и:
  2. добавете 1) заедно
  3. добавете към 2)
  4. добави 3) към
x = tf.get_variable("x", dtype=tf.int32,  initializer=tf.constant([5]))
z = tf.get_variable("z", dtype=tf.int32,  initializer=tf.constant([6]))
c = tf.constant([5], name =	"constant")square = tf.constant([2], name =	"square")
f = tf.multiply(x, z) + tf.pow(x, square) + z + c

Обяснение на кода

  • x: Инициализирайте променлива, наречена x, с постоянна стойност 5
  • z: Инициализирайте променлива, наречена z, с постоянна стойност 6
  • c: Инициализирайте постоянен тензор, наречен c, с постоянна стойност 5
  • квадрат: Инициализирайте постоянен тензор, наречен квадрат с постоянна стойност 2
  • f: Конструирайте оператора

В този пример избираме да запазим стойностите на променливите фиксирани. Също така създадохме постоянен тензор, наречен c, който е постоянният параметър във функцията f. Приема фиксирана стойност 5. На графиката можете да видите този параметър в тензора, наречен константа.

Ние също конструирахме постоянен тензор за степента в оператора tf.pow(). Не е необходимо. Направихме го, за да можете да видите името на тензора в графиката. Това е кръгът, наречен квадрат.

От графиката можете да разберете какво ще се случи с тензорите и как може да върне резултат от 66.

Кодът по-долу оценява функцията в сесия.

init = tf.global_variables_initializer() # prepare to initialize all variables
with tf.Session() as sess:    
	init.run() # Initialize x and y    
    function_result = f.eval()
print(function_result)

Продукция

[66]

Oбобщение

TensorFlow работи около:

  • Крива: Изчислителна среда, съдържаща операциите и тензорите
  • тензори: Представлява данните (или стойността), които ще текат в графиката. Това е ръбът в графиката
  • сесии: Позволява изпълнението на операциите

Създайте постоянен тензор

постоянен обект
D0 tf.constant(1, tf.int16)
D1 tf.constant([1,3,5], tf.int16)
D2 tf.constant([[1, 2], [3, 4]],tf.int16)
D3 tf.constant([[[1, 2],[3, 4], [5, 6]]], tf.int16)

Създайте оператор

Създайте оператор Обект
a + b tf.add(a, b)
а*б tf.multiply(a, b)

Създайте променлив тензор

Създайте променлива обект
рандомизирана стойност tf.get_variable("var", [1, 2])
инициализирана първа стойност tf.get_variable(“var_init_2”, dtype=tf.int32, initializer=[[1, 2], [3, 4] ])

Отворете сесия

Сесия обект
Създайте сесия tf.Session()
Стартирайте сесия tf.Session.run()
Оценете тензор име_на_променлива.eval()
Затворете сесия sess.close()
Сесия по блок с tf.Session() като sess: