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
텐서에서 여러 일반적인 수학 연산을 할 수 있습니다(TF API). 다음 코드는 각기 정확히 6개 요소를 가지는 두 벡터(1-D 텐서)를 만들고 조작합니다.
In [0]:
with tf.Graph().as_default():
# Create a six-element vector (1-D tensor).
primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)
# Create another six-element vector. Each element in the vector will be
# initialized to 1. The first argument is the shape of the tensor (more
# on shapes below).
ones = tf.ones([6], dtype=tf.int32)
# Add the two vectors. The resulting tensor is a six-element vector.
just_beyond_primes = tf.add(primes, ones)
# Create a session to run the default graph.
with tf.Session() as sess:
print(just_beyond_primes.eval())
형태는 텐서의 크기와 차원 수를 결정하는 데 사용됩니다. 텐서 형태는 목록
으로 표현하며, i
번째 요소는 i
차원에서 크기를 나타냅니다. 그리고 이 목록의 길이는 텐서의 순위(예: 차원 수)를 나타냅니다.
자세한 정보는 텐서플로우 문서를 참조하세요.
몇 가지 기본 예:
In [0]:
with tf.Graph().as_default():
# 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])
with tf.Session() as sess:
print('scalar has shape', scalar.get_shape(), 'and value:\n', scalar.eval())
print('vector has shape', vector.get_shape(), 'and value:\n', vector.eval())
print('matrix has shape', matrix.get_shape(), 'and value:\n', matrix.eval())
수학에서는 같은 형태의 텐서에서 요소간 연산(예: add 및 equals)만 실행할 수 있습니다. 하지만 텐서플로우에서는 텐서에서 기존에는 호환되지 않았던 연산을 실행할 수 있습니다. 텐서플로우는 요소간 연산에서 더 작은 배열을 확장하여 더 큰 배열과 같은 형태를 가지게 하는 브로드캐스팅(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 브로드캐스팅 문서에 이해하기 쉽게 잘 설명되어 있습니다.
다음 코드는 앞서 설명한 텐서 덧셈을 실행하지만 브로드캐스팅을 사용합니다.
In [0]:
with tf.Graph().as_default():
# Create a six-element vector (1-D tensor).
primes = tf.constant([2, 3, 5, 7, 11, 13], dtype=tf.int32)
# Create a constant scalar with value 1.
ones = tf.constant(1, dtype=tf.int32)
# Add the two tensors. The resulting tensor is a six-element vector.
just_beyond_primes = tf.add(primes, ones)
with tf.Session() as sess:
print(just_beyond_primes.eval())
In [0]:
with tf.Graph().as_default():
# Create a matrix (2-d tensor) with 3 rows and 4 columns.
x = tf.constant([[5, 2, 4, 3], [5, 1, 6, -2], [-1, 3, -1, -2]],
dtype=tf.int32)
# Create a matrix with 4 rows and 2 columns.
y = tf.constant([[2, 2], [3, 5], [4, 5], [1, 6]], dtype=tf.int32)
# Multiply `x` by `y`.
# The resulting matrix will have 3 rows and 2 columns.
matrix_multiply_result = tf.matmul(x, y)
with tf.Session() as sess:
print(matrix_multiply_result.eval())
In [0]:
with tf.Graph().as_default():
# 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)
# Reshape the 8x2 matrix into a 2x8 matrix.
reshaped_2x8_matrix = tf.reshape(matrix, [2,8])
# Reshape the 8x2 matrix into a 4x4 matrix
reshaped_4x4_matrix = tf.reshape(matrix, [4,4])
with tf.Session() as sess:
print("Original matrix (8x2):")
print(matrix.eval())
print("Reshaped matrix (2x8):")
print(reshaped_2x8_matrix.eval())
print("Reshaped matrix (4x4):")
print(reshaped_4x4_matrix.eval())
또한 tf.reshape
를 사용하여 텐서의 차원 수(\'순위\')를 변경할 수도 있습니다.
예를 들어 8x2 텐서를 3-D 2x2x4 텐서나 1-D 16-요소 텐서로 변경할 수 있습니다.
In [0]:
with tf.Graph().as_default():
# 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)
# Reshape the 8x2 matrix into a 3-D 2x2x4 tensor.
reshaped_2x2x4_tensor = tf.reshape(matrix, [2,2,4])
# Reshape the 8x2 matrix into a 1-D 16-element tensor.
one_dimensional_vector = tf.reshape(matrix, [16])
with tf.Session() as sess:
print("Original matrix (8x2):")
print(matrix.eval())
print("Reshaped 3-D tensor (2x2x4):")
print(reshaped_2x2x4_tensor.eval())
print("1-D vector:")
print(one_dimensional_vector.eval())
In [0]:
# Write your code for Task 1 here.
In [0]:
with tf.Graph().as_default(), tf.Session() as sess:
# Task: Reshape two tensors in order to multiply them
# Here are the original operands, which are incompatible
# for matrix multiplication:
a = tf.constant([5, 3, 2, 7, 1, 4])
b = tf.constant([4, 6, 3])
# We need to reshape at least one of these operands so that
# the number of columns in the first operand equals the number
# of rows in the second operand.
# Reshape vector "a" into a 2-D 2x3 matrix:
reshaped_a = tf.reshape(a, [2,3])
# Reshape vector "b" into a 2-D 3x1 matrix:
reshaped_b = tf.reshape(b, [3,1])
# The number of columns in the first matrix now equals
# the number of rows in the second matrix. Therefore, you
# can matrix mutiply the two operands.
c = tf.matmul(reshaped_a, reshaped_b)
print(c.eval())
# An alternate approach: [6,1] x [1, 3] -> [6,3]
In [0]:
g = tf.Graph()
with g.as_default():
# Create a variable with the initial value 3.
v = tf.Variable([3])
# Create a variable of shape [1], with a random initial value,
# sampled from a normal distribution with mean 1 and standard deviation 0.35.
w = tf.Variable(tf.random_normal([1], mean=1.0, stddev=0.35))
텐서플로우의 한 가지 특징은 변수 초기화가 자동으로 실행되지 않는다는 것입니다. 예를 들어 다음 블록에서는 오류가 발생합니다.
In [0]:
with g.as_default():
with tf.Session() as sess:
try:
v.eval()
except tf.errors.FailedPreconditionError as e:
print("Caught expected error: ", e)
변수를 초기화하는 가장 쉬운 방법은 global_variables_initializer
를 호출하는 것입니다. eval()
과 거의 비슷한 Session.run()
의 사용을 참고하세요.
In [0]:
with g.as_default():
with tf.Session() as sess:
initialization = tf.global_variables_initializer()
sess.run(initialization)
# Now, variables can be accessed normally, and have values assigned to them.
print(v.eval())
print(w.eval())
초기화된 변수는 같은 세션 내에서는 값을 유지합니다. 하지만 새 세션을 시작하면 다시 초기화해야 합니다.
In [0]:
with g.as_default():
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# These three prints will print the same value.
print(w.eval())
print(w.eval())
print(w.eval())
변수 값을 변경하려면 할당
작업을 사용합니다. 할당
작업을 만들기만 하면 실행되는 것은 아닙니다. 초기화와 마찬가지로 할당 작업을 실행
해야 변수 값이 업데이트됩니다.
In [0]:
with g.as_default():
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# This should print the variable's initial value.
print(v.eval())
assignment = tf.assign(v, [7])
# The variable has not been changed yet!
print(v.eval())
# Execute the assignment op.
sess.run(assignment)
# Now the variable is updated.
print(v.eval())
로드 및 저장과 같이 여기에서 다루지 않은 변수에 관한 주제도 더 많이 있습니다. 자세히 알아보려면 텐서플로우 문서를 참조하세요.
주사위 시뮬레이션을 만듭니다. 여기에서 10x3
2-D 텐서를 생성하며 조건은 다음과 같습니다.
1
및 2
는 각각 주사위 1개를 1번 던졌을 때의 값입니다.3
은 같은 줄의 열 1
과 2
의 합입니다.예를 들어 첫 번째 행의 값은 다음과 같을 수 있습니다.
1
은 4
2
는 3
3
은 7
텐서플로우 문서를 참조하여 이 문제를 해결해 보세요.
In [0]:
# Write your code for Task 2 here.
In [0]:
with tf.Graph().as_default(), tf.Session() as sess:
# Task 2: Simulate 10 throws of two dice. Store the results
# in a 10x3 matrix.
# We're going to place dice throws inside two separate
# 10x1 matrices. We could have placed dice throws inside
# a single 10x2 matrix, but adding different columns of
# the same matrix is tricky. We also could have placed
# dice throws inside two 1-D tensors (vectors); doing so
# would require transposing the result.
dice1 = tf.Variable(tf.random_uniform([10, 1],
minval=1, maxval=7,
dtype=tf.int32))
dice2 = tf.Variable(tf.random_uniform([10, 1],
minval=1, maxval=7,
dtype=tf.int32))
# We may add dice1 and dice2 since they share the same shape
# and size.
dice_sum = tf.add(dice1, dice2)
# We've got three separate 10x1 matrices. To produce a single
# 10x3 matrix, we'll concatenate them along dimension 1.
resulting_matrix = tf.concat(
values=[dice1, dice2, dice_sum], axis=1)
# The variables haven't been initialized within the graph yet,
# so let's remedy that.
sess.run(tf.global_variables_initializer())
print(resulting_matrix.eval())