<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Copyright 2017 Google LLC.
Step1:  # 텐서 만들기 및 조작
학습 목표
Step2:  ## 벡터 덧셈
텐서에서 여러 일반적인 수학 연산을 할 수 있습니다(TF API). 다음 코드는
각기 정확히 6개 요소를 가지는 두 벡터(1-D 텐서)를 만들고 조작합니다.
Step3:  ### 텐서 형태
형태는 텐서의 크기와 차원 수를 결정하는 데 사용됩니다. 텐서 형태는 목록으로 표현하며, i번째 요소는 i 차원에서 크기를 나타냅니다. 그리고 이 목록의 길이는 텐서의 순위(예
Step4:  ### 브로드캐스팅
수학에서는 같은 형태의 텐서에서 요소간 연산(예
Step5:  ## 행렬 곱셈
선형대수학에서 두 개의 행렬을 곱할 때는 첫 번째 행렬의 열 수가 두 번째
행렬의 행 수와 같아야 했습니다.
3x4 행렬과 4x2 행렬을 곱하는 것은 유효합니다. 이렇게 하면 3x2 행렬을 얻을 수 있습니다.
4x2 행렬과 3x4 행렬을 곱하는 것은 유효하지 않습니다.
Step6:  ## 텐서 형태 변경
텐서 덧셈과 행렬 곱셈에서 각각 피연산자에 제약조건을 부여하면
텐서플로우 프로그래머는 자주 텐서의 형태를 변경해야 합니다. 
tf.reshape 메서드를 사용하여 텐서의 형태를 변경할 수 있습니다. 
예를 들어 8x2 텐서를 2x8 텐서나 4x4 텐서로 형태를 변경할 수 있습니다.
Step7:  또한 tf.reshape를 사용하여 텐서의 차원 수(\'순위\')를 변경할 수도 있습니다.
예를 들어 8x2 텐서를 3-D 2x2x4 텐서나 1-D 16-요소 텐서로 변경할 수 있습니다.
Step8:  ### 실습 #1
Step9:  ### 해결 방법
해결 방법을 보려면 아래를 클릭하세요.
Step10:  ## 변수, 초기화, 할당
지금까지 수행한 모든 연산은 정적 값(tf.constant)에서 실행되었고; eval()을 호출하면 항상 같은 결과가 반환되었습니다. 텐서플로우에서는 변수 객체를 정의할 수 있으며, 변수 값은 변경할 수 있습니다. 
변수를 만들 때 초기 값을 명시적으로 설정하거나 이니셜라이저(예
Step11:  텐서플로우의 한 가지 특징은 변수 초기화가 자동으로 실행되지 않는다는 것입니다. 예를 들어 다음 블록에서는 오류가 발생합니다.
Step12:  변수를 초기화하는 가장 쉬운 방법은 global_variables_initializer를 호출하는 것입니다. eval()과 거의 비슷한 Session.run()의 사용을 참고하세요.
Step13:  초기화된 변수는 같은 세션 내에서는 값을 유지합니다. 하지만 새 세션을 시작하면 다시 초기화해야 합니다.
Step14:  변수 값을 변경하려면 할당 작업을 사용합니다. 할당 작업을 만들기만 하면 실행되는 것은 아닙니다. 초기화와 마찬가지로 할당 작업을 실행해야 변수 값이 업데이트됩니다.
Step15:  로드 및 저장과 같이 여기에서 다루지 않은 변수에 관한 주제도 더 많이 있습니다. 자세히 알아보려면 텐서플로우 문서를 참조하세요.
### 실습 #2
Step16:  ### 해결 방법
해결 방법을 보려면 아래를 클릭하세요.
<ASSISTANT_TASK:>
Python Code:
# 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.
Explanation: Copyright 2017 Google LLC.
End of explanation
from __future__ import print_function
import tensorflow as tf
Explanation: # 텐서 만들기 및 조작
학습 목표:
  * 텐서플로우 변수 초기화 및 할당
  * 텐서 만들기 및 조작
  * 선형대수학의 덧셈 및 곱셈 지식 되살리기(이 주제가 생소한 경우 행렬 덧셈 및 곱셈 참조)
  * 기본 텐서플로우 수학 및 배열 작업에 익숙해지기
End of explanation
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())
Explanation: ## 벡터 덧셈
텐서에서 여러 일반적인 수학 연산을 할 수 있습니다(TF API). 다음 코드는
각기 정확히 6개 요소를 가지는 두 벡터(1-D 텐서)를 만들고 조작합니다.
End of explanation
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())
Explanation: ### 텐서 형태
형태는 텐서의 크기와 차원 수를 결정하는 데 사용됩니다. 텐서 형태는 목록으로 표현하며, i번째 요소는 i 차원에서 크기를 나타냅니다. 그리고 이 목록의 길이는 텐서의 순위(예: 차원 수)를 나타냅니다.
자세한 정보는 텐서플로우 문서를 참조하세요.
몇 가지 기본 예:
End of explanation
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())
Explanation: ### 브로드캐스팅
수학에서는 같은 형태의 텐서에서 요소간 연산(예: 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 브로드캐스팅 문서에 이해하기 쉽게 잘 설명되어 있습니다.
다음 코드는 앞서 설명한 텐서 덧셈을 실행하지만 브로드캐스팅을 사용합니다.
End of explanation
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())
Explanation: ## 행렬 곱셈
선형대수학에서 두 개의 행렬을 곱할 때는 첫 번째 행렬의 열 수가 두 번째
행렬의 행 수와 같아야 했습니다.
3x4 행렬과 4x2 행렬을 곱하는 것은 유효합니다. 이렇게 하면 3x2 행렬을 얻을 수 있습니다.
4x2 행렬과 3x4 행렬을 곱하는 것은 유효하지 않습니다.
End of explanation
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())
Explanation: ## 텐서 형태 변경
텐서 덧셈과 행렬 곱셈에서 각각 피연산자에 제약조건을 부여하면
텐서플로우 프로그래머는 자주 텐서의 형태를 변경해야 합니다. 
tf.reshape 메서드를 사용하여 텐서의 형태를 변경할 수 있습니다. 
예를 들어 8x2 텐서를 2x8 텐서나 4x4 텐서로 형태를 변경할 수 있습니다.
End of explanation
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())
Explanation: 또한 tf.reshape를 사용하여 텐서의 차원 수(\'순위\')를 변경할 수도 있습니다.
예를 들어 8x2 텐서를 3-D 2x2x4 텐서나 1-D 16-요소 텐서로 변경할 수 있습니다.
End of explanation
  # Write your code for Task 1 here.
Explanation: ### 실습 #1: 두 개의 텐서를 곱하기 위해 두 텐서의 형태를 변경합니다.
다음 두 벡터는 행렬 곱셈과 호환되지 않습니다.
a = tf.constant([5, 3, 2, 7, 1, 4])
b = tf.constant([4, 6, 3])
이 벡터를 행렬 곱셈에 호환될 수 있는 피연산자로 형태를 변경하세요.
그런 다음 형태가 변경된 텐서에서 행렬 곱셈 작업을 호출하세요.
End of explanation
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]
Explanation: ### 해결 방법
해결 방법을 보려면 아래를 클릭하세요.
End of explanation
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))
Explanation: ## 변수, 초기화, 할당
지금까지 수행한 모든 연산은 정적 값(tf.constant)에서 실행되었고; eval()을 호출하면 항상 같은 결과가 반환되었습니다. 텐서플로우에서는 변수 객체를 정의할 수 있으며, 변수 값은 변경할 수 있습니다. 
변수를 만들 때 초기 값을 명시적으로 설정하거나 이니셜라이저(예: 분포)를 사용할 수 있습니다.
End of explanation
with g.as_default():
  with tf.Session() as sess:
    try:
      v.eval()
    except tf.errors.FailedPreconditionError as e:
      print("Caught expected error: ", e)
Explanation: 텐서플로우의 한 가지 특징은 변수 초기화가 자동으로 실행되지 않는다는 것입니다. 예를 들어 다음 블록에서는 오류가 발생합니다.
End of explanation
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())
Explanation: 변수를 초기화하는 가장 쉬운 방법은 global_variables_initializer를 호출하는 것입니다. eval()과 거의 비슷한 Session.run()의 사용을 참고하세요.
End of explanation
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())
Explanation: 초기화된 변수는 같은 세션 내에서는 값을 유지합니다. 하지만 새 세션을 시작하면 다시 초기화해야 합니다.
End of explanation
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())
Explanation: 변수 값을 변경하려면 할당 작업을 사용합니다. 할당 작업을 만들기만 하면 실행되는 것은 아닙니다. 초기화와 마찬가지로 할당 작업을 실행해야 변수 값이 업데이트됩니다.
End of explanation
# Write your code for Task 2 here.
Explanation: 로드 및 저장과 같이 여기에서 다루지 않은 변수에 관한 주제도 더 많이 있습니다. 자세히 알아보려면 텐서플로우 문서를 참조하세요.
### 실습 #2: 주사위 2개 10번 굴리기를 시뮬레이션합니다.
주사위 시뮬레이션을 만듭니다. 여기에서 10x3 2-D 텐서를 생성하며 조건은 다음과 같습니다.
열 1 및 2는 각각 주사위 1개를 1번 던졌을 때의 값입니다.
열 3은 같은 줄의 열 1과 2의 합입니다.
예를 들어 첫 번째 행의 값은 다음과 같을 수 있습니다.
열 1은 4
열 2는 3
열 3은 7
텐서플로우 문서를 참조하여 이 문제를 해결해 보세요.
End of explanation
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())
Explanation: ### 해결 방법
해결 방법을 보려면 아래를 클릭하세요.
End of explanation
<END_TASK>