{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "Tce3stUlHN0L" }, "source": [ "##### Copyright 2020 The TensorFlow Authors." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "cellView": "form", "execution": { "iopub.execute_input": "2022-12-14T21:07:23.074997Z", "iopub.status.busy": "2022-12-14T21:07:23.074387Z", "iopub.status.idle": "2022-12-14T21:07:23.078454Z", "shell.execute_reply": "2022-12-14T21:07:23.077784Z" }, "id": "tuOe1ymfHZPu" }, "outputs": [], "source": [ "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", "# you may not use this file except in compliance with the License.\n", "# You may obtain a copy of the License at\n", "#\n", "# https://www.apache.org/licenses/LICENSE-2.0\n", "#\n", "# Unless required by applicable law or agreed to in writing, software\n", "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", "# See the License for the specific language governing permissions and\n", "# limitations under the License." ] }, { "cell_type": "markdown", "metadata": { "id": "qFdPvlXBOdUN" }, "source": [ "# 변수 소개" ] }, { "cell_type": "markdown", "metadata": { "id": "MfBg1C5NB3X0" }, "source": [ "\n", " \n", " \n", " \n", " \n", "
TensorFlow.org에서 보기Google Colab에서 실행GitHub에서 소스 보기노트북 다운로드
" ] }, { "cell_type": "markdown", "metadata": { "id": "AKhB9CMxndDs" }, "source": [ "TensorFlow **변수**는 프로그램이 조작하는 공유 영구 상태를 나타내는 권장 방법입니다. 이 가이드는 TensorFlow에서 `tf.Variable` 인스턴스를 작성, 업데이트 및 관리하는 방법을 설명합니다.\n", "\n", "변수는 `tf.Variable` 클래스를 통해 생성 및 추적됩니다. `tf.Variable`은 ops를 실행하여 값을 변경할 수 있는 텐서를 나타냅니다. 특정 ops를 사용하면 이 텐서의 값을 읽고 수정할 수 있습니다. `tf.keras`와 같은 상위 수준의 라이브러리는 `tf.Variable`을 사용하여 모델 매개변수를 저장합니다. " ] }, { "cell_type": "markdown", "metadata": { "id": "xZoJJ4vdvTrD" }, "source": [ "## 설정\n", "\n", "변수 배치에 대해 설명하는 노트북입니다. 변수가 어떤 기기에 배치되었는지 보려면 이 줄의 주석을 해제하세요." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:07:23.082354Z", "iopub.status.busy": "2022-12-14T21:07:23.081749Z", "iopub.status.idle": "2022-12-14T21:07:24.996986Z", "shell.execute_reply": "2022-12-14T21:07:24.996289Z" }, "id": "7tUZJk7lDiGo" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "2022-12-14 21:07:24.023879: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n", "2022-12-14 21:07:24.023977: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n", "2022-12-14 21:07:24.023986: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n" ] } ], "source": [ "import tensorflow as tf\n", "\n", "# Uncomment to see where your variables get placed (see below)\n", "# tf.debugging.set_log_device_placement(True)" ] }, { "cell_type": "markdown", "metadata": { "id": "vORGXDarogWm" }, "source": [ "## 변수 만들기\n", "\n", "변수를 작성하려면 초기값을 제공합니다. `tf.Variable`은 초기화 값과 같은 `dtype`을 갖습니다." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:07:25.001628Z", "iopub.status.busy": "2022-12-14T21:07:25.000959Z", "iopub.status.idle": "2022-12-14T21:07:28.434456Z", "shell.execute_reply": "2022-12-14T21:07:28.433735Z" }, "id": "dsYXSqleojj7" }, "outputs": [], "source": [ "my_tensor = tf.constant([[1.0, 2.0], [3.0, 4.0]])\n", "my_variable = tf.Variable(my_tensor)\n", "\n", "# Variables can be all kinds of types, just like tensors\n", "bool_variable = tf.Variable([False, False, False, True])\n", "complex_variable = tf.Variable([5 + 4j, 6 + 1j])" ] }, { "cell_type": "markdown", "metadata": { "id": "VQHwJ_Itoujf" }, "source": [ "변수는 텐서처럼 보이고 작동하며, 실제로 `tf.Tensor`에서 지원되는 데이터 구조입니다. 텐서와 마찬가지로, `dtype`과 형상을 가지며 NumPy로 내보낼 수 있습니다." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:07:28.438089Z", "iopub.status.busy": "2022-12-14T21:07:28.437803Z", "iopub.status.idle": "2022-12-14T21:07:28.444172Z", "shell.execute_reply": "2022-12-14T21:07:28.443573Z" }, "id": "GhNfPwCYpvlq" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Shape: (2, 2)\n", "DType: \n", "As NumPy: [[1. 2.]\n", " [3. 4.]]\n" ] } ], "source": [ "print(\"Shape: \", my_variable.shape)\n", "print(\"DType: \", my_variable.dtype)\n", "print(\"As NumPy: \", my_variable.numpy())" ] }, { "cell_type": "markdown", "metadata": { "id": "eZmSBYViqDoU" }, "source": [ "변수를 재구성할 수는 없지만, 대부분의 텐서 연산은 예상대로 변수에 대해 작동합니다." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:07:28.447572Z", "iopub.status.busy": "2022-12-14T21:07:28.447121Z", "iopub.status.idle": "2022-12-14T21:07:28.458077Z", "shell.execute_reply": "2022-12-14T21:07:28.457403Z" }, "id": "TrIaExVNp_LK" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A variable: \n", "\n", "Viewed as a tensor: tf.Tensor(\n", "[[1. 2.]\n", " [3. 4.]], shape=(2, 2), dtype=float32)\n", "\n", "Index of highest value: tf.Tensor([1 1], shape=(2,), dtype=int64)\n", "\n", "Copying and reshaping: tf.Tensor([[1. 2. 3. 4.]], shape=(1, 4), dtype=float32)\n" ] } ], "source": [ "print(\"A variable:\", my_variable)\n", "print(\"\\nViewed as a tensor:\", tf.convert_to_tensor(my_variable))\n", "print(\"\\nIndex of highest value:\", tf.math.argmax(my_variable))\n", "\n", "# This creates a new tensor; it does not reshape the variable.\n", "print(\"\\nCopying and reshaping: \", tf.reshape(my_variable, [1,4]))" ] }, { "cell_type": "markdown", "metadata": { "id": "qbLCcG6Pc29Y" }, "source": [ "위에서 언급했듯이, 변수는 텐서에 의해 지원됩니다. `tf.Variable.assign`을 사용하여 텐서를 재할당할 수 있습니다. `assign`을 호출해도 (일반적으로) 새로운 텐서를 할당하지 않고, 대신 기존 텐서의 메모리가 재사용됩니다." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:07:28.461436Z", "iopub.status.busy": "2022-12-14T21:07:28.461034Z", "iopub.status.idle": "2022-12-14T21:07:28.469243Z", "shell.execute_reply": "2022-12-14T21:07:28.468599Z" }, "id": "yeEpO309QbB2" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ValueError: Cannot assign value to variable ' Variable:0': Shape mismatch.The variable shape (2,), and the assigned value shape (3,) are incompatible.\n" ] } ], "source": [ "a = tf.Variable([2.0, 3.0])\n", "# This will keep the same dtype, float32\n", "a.assign([1, 2]) \n", "# Not allowed as it resizes the variable: \n", "try:\n", " a.assign([1.0, 2.0, 3.0])\n", "except Exception as e:\n", " print(f\"{type(e).__name__}: {e}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "okeywjLdQ1tY" }, "source": [ "연산에서 텐서와 같은 변수를 사용하는 경우, 일반적으로 지원 텐서에서 작동합니다.\n", "\n", "기존 변수에서 새 변수를 만들면 지원 텐서가 복제됩니다. 두 변수는 같은메모리를 공유하지 않습니다." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:07:28.472194Z", "iopub.status.busy": "2022-12-14T21:07:28.471750Z", "iopub.status.idle": "2022-12-14T21:07:28.482597Z", "shell.execute_reply": "2022-12-14T21:07:28.481943Z" }, "id": "2CnfGc6ucbXc" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5. 6.]\n", "[2. 3.]\n", "[7. 9.]\n", "[0. 0.]\n" ] } ], "source": [ "a = tf.Variable([2.0, 3.0])\n", "# Create b based on the value of a\n", "b = tf.Variable(a)\n", "a.assign([5, 6])\n", "\n", "# a and b are different\n", "print(a.numpy())\n", "print(b.numpy())\n", "\n", "# There are other versions of assign\n", "print(a.assign_add([2,3]).numpy()) # [7. 9.]\n", "print(a.assign_sub([7,9]).numpy()) # [0. 0.]" ] }, { "cell_type": "markdown", "metadata": { "id": "ZtzepotYUe7B" }, "source": [ "## 수명 주기, 이름 지정 및 감시\n", "\n", "파이썬 기반 TensorFlow에서 `tf.Variable` 인스턴스는 다른 Python 객체와 같은 수명 주기를 갖습니다. 변수에 대한 참조가 없으면 자동으로 할당이 해제됩니다.\n", "\n", "변수를 추적하고 디버그하는 데 도움이 되는 변수의 이름을 지정할 수도 있습니다. 두 변수에 같은 이름을 지정할 수 있습니다." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:07:28.485890Z", "iopub.status.busy": "2022-12-14T21:07:28.485287Z", "iopub.status.idle": "2022-12-14T21:07:28.493227Z", "shell.execute_reply": "2022-12-14T21:07:28.492641Z" }, "id": "VBFbzKj8RaPf" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[False False]\n", " [False False]], shape=(2, 2), dtype=bool)\n" ] } ], "source": [ "# Create a and b; they will have the same name but will be backed by\n", "# different tensors.\n", "a = tf.Variable(my_tensor, name=\"Mark\")\n", "# A new variable with the same name, but different value\n", "# Note that the scalar add is broadcast\n", "b = tf.Variable(my_tensor + 1, name=\"Mark\")\n", "\n", "# These are elementwise-unequal, despite having the same name\n", "print(a == b)" ] }, { "cell_type": "markdown", "metadata": { "id": "789QikItVA_E" }, "source": [ "모델을 저장하고 로드할 때 변수 이름이 유지됩니다. 기본적으로 모델의 변수는 고유한 변수 이름이 자동으로 지정되므로 원치 않는 한 직접 할당할 필요가 없습니다.\n", "\n", "변수는 구별을 위해 중요하지만, 일부 변수는 구별할 필요가 없습니다. 생성 시 `trainable`을 false로 설정하여 변수의 그래디언트를 끌 수 있습니다. 그래디언트가 필요하지 않은 변수의 예는 훈련 단계 카운터입니다." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:07:28.496423Z", "iopub.status.busy": "2022-12-14T21:07:28.496070Z", "iopub.status.idle": "2022-12-14T21:07:28.500880Z", "shell.execute_reply": "2022-12-14T21:07:28.500310Z" }, "id": "B5Sj1DqhbZvx" }, "outputs": [], "source": [ "step_counter = tf.Variable(1, trainable=False)" ] }, { "cell_type": "markdown", "metadata": { "id": "DD_xfDLDTDNU" }, "source": [ "## 변수 및 텐서 배치하기\n", "\n", "더 나은 성능을 위해 TensorFlow는 `dtype`과 호환되는 가장 빠른 기기에 텐서 및 변수를 배치하려고 시도합니다. 이는 대부분의 변수가 GPU(사용 가능한 경우)에 배치됨을 의미합니다.\n", "\n", "그러나 우리는 이것을 재정의할 수 있습니다. 이 코드에서, GPU가 사용가능함에서도 우리는 부동 텐서와 변수를 CPU에 배치할 수 있습니다. 기기배치에 로그인을 함으로써 ( [Setup](#scrollTo=xZoJJ4vdvTrD) 참조), 변수가 어디에 위치해있는지 확인할 수 있습니다.\n", "\n", "참고: 수동 배치도 가능하지만, [분배 전략](distributed_training.ipynb)을 사용하여 더 편리하고 확장 가능하게 계산을 최적화 할 수 있습니다.\n", "\n", "GPU가 있거나 없는 서로 다른 백엔드에서 이 노트북을 실행하면 서로 다른 로깅이 표시됩니다. *세션 시작 시 기기 배치 로깅을 켜야 합니다.*" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:07:28.504261Z", "iopub.status.busy": "2022-12-14T21:07:28.503756Z", "iopub.status.idle": "2022-12-14T21:07:28.530452Z", "shell.execute_reply": "2022-12-14T21:07:28.529857Z" }, "id": "2SjpD7wVUSBJ" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[22. 28.]\n", " [49. 64.]], shape=(2, 2), dtype=float32)\n" ] } ], "source": [ "with tf.device('CPU:0'):\n", "\n", " # Create some tensors\n", " a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])\n", " b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])\n", " c = tf.matmul(a, b)\n", "\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": { "id": "PXbh-p2BXKcr" }, "source": [ "한 기기에서 변수 또는 텐서의 위치를 설정하고 다른 기기에서 계산을 수행할 수 있습니다. 이 경우, 기기 간에 데이터를 복사해야 하므로 지연이 발생합니다.\n", "\n", "GPU 작업자가 여러 개이지만 변수의 사본이 하나만 필요한 경우에 수행할 수 있습니다." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2022-12-14T21:07:28.533362Z", "iopub.status.busy": "2022-12-14T21:07:28.533017Z", "iopub.status.idle": "2022-12-14T21:07:28.542023Z", "shell.execute_reply": "2022-12-14T21:07:28.541434Z" }, "id": "dgWHN3QSfNiQ" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor(\n", "[[ 1. 4. 9.]\n", " [ 4. 10. 18.]], shape=(2, 3), dtype=float32)\n" ] } ], "source": [ "with tf.device('CPU:0'):\n", " a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])\n", " b = tf.Variable([[1.0, 2.0, 3.0]])\n", "\n", "with tf.device('GPU:0'):\n", " # Element-wise multiply\n", " k = a * b\n", "\n", "print(k)" ] }, { "cell_type": "markdown", "metadata": { "id": "fksvRaqoYfay" }, "source": [ "주의: `tf.config.set_soft_device_placement` 이 기본적으로 항상 켜져있기 때문에, GPU가 없는 기기에서 이 코드를 실행하더라도 코드는 계속 실행됩니다. 곱셈 단계는 CPU에서 실행됩니다.\n", "\n", "분산 훈련에 대한 자세한 내용은 [가이드](distributed_training.ipynb)를 참조하세요." ] }, { "cell_type": "markdown", "metadata": { "id": "SzCkWlF2S4yo" }, "source": [ "## 다음 단계\n", "\n", "변수들이 일반적으로 사용되는 방식을 이해하려면, [automatic differentiation](autodiff.ipynb)에서 우리의 가이드를 참조하세요." ] } ], "metadata": { "colab": { "collapsed_sections": [], "name": "variable.ipynb", "toc_visible": true }, "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.16" } }, "nbformat": 4, "nbformat_minor": 0 }