├── Keras_Basic_Tutorial_Chanjun_Park.ipynb ├── Pytorch_Basic_Tutorial_Chanjun_Park.ipynb └── README.md /Keras_Basic_Tutorial_Chanjun_Park.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Keras_Basic_Tutorial_Chanjun_Park.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [] 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "accelerator": "GPU" 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "id": "t8_IQwXBrC3Y", 21 | "colab_type": "text" 22 | }, 23 | "source": [ 24 | "제작자: Chanjun Park (박찬준)
\n", 25 | "소속: Korea University NLP&AI Lab (고려대학교 자연어처리&인공지능 연구실)
\n", 26 | "\n", 27 | "튜토리얼 명: Keras로 배우는 Artificial Neural Network" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "id": "yiHva9JjqyDI", 34 | "colab_type": "text" 35 | }, 36 | "source": [ 37 | "<1>간단한 인공신경망 실습을 진행해봅시다.\n", 38 | "숫자 5개 중 2개를 학습해 나머지 3개를 예측해봅시다." 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "metadata": { 44 | "id": "_cNarp4Fl7l2", 45 | "colab_type": "code", 46 | "colab": {} 47 | }, 48 | "source": [ 49 | "import keras\n", 50 | "import numpy\n", 51 | "\n", 52 | "x=numpy.array([0,1,2,3,4]) #숫자 5개 선언\n", 53 | "y=x*2+1 #y값 정의\n", 54 | "\n", 55 | "model=keras.models.Sequential() #인스턴스 만들기\n", 56 | "model.add(keras.layers.Dense(1,input_shape=(1,)))#계층 추가/입력은 1개\n", 57 | "\n", 58 | "model.compile('SGD','mse') #어떻게 학습할지 적기 (최적화알고리즘, 손실함수)\n", 59 | "\n", 60 | "model.fit(x[:2],y[:2],epochs=1000,verbose=0) #실제 학습하기 , verbose가 0일경우 학습진행 상황 표시 X, 2개는 학습 진행\n", 61 | "\n", 62 | "print('Targets: ',y[2:]) #3개는 예측을 진행\n", 63 | "print('Predictions:',model.predict(x[2:]).flatten()) #실제 예측하기\n", 64 | "print('Predictions:',model.predict(x[2:])) #flatten을 빼면 각각 표시됨." 65 | ], 66 | "execution_count": 0, 67 | "outputs": [] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": { 72 | "id": "RybMNwYLrHBf", 73 | "colab_type": "text" 74 | }, 75 | "source": [ 76 | "ANN (인공신경망)\n", 77 | "얕은 신경망 shallow Neural Network\n", 78 | "\n", 79 | "핵심은 입력,은닉,출력 계층으로 이루어져 있다 !\n", 80 | "\n", 81 | "1단계: 입력이 들어오면 가중치 행렬을 곱해준다.
\n", 82 | "2단계: 이를 은닉 행렬의 입력으로 넣어준다.
\n", 83 | "3단계: 은닉 계층에서는 입력된 값에 활성화 함수를 적용한다. 이는 비선형성이라는 특징을 부여한다.
\n", 84 | "4단계: 여기에 또 다시 가중치 행렬을 곱하고 출력계층으로 보내준다.
\n", 85 | "5단계: 출력계층은 마찬가지로 활성화 함수를 적용하고 최종적으로 출력값을 내보낸다.
\n", 86 | "6단계: 만약 분류 문제일 경우 소프트맥스 연산을 사용한다. " 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": { 92 | "id": "fORI8jUisacX", 93 | "colab_type": "text" 94 | }, 95 | "source": [ 96 | "분류와 회귀
\n", 97 | "분류: 0~9 숫자 중 무엇이냐, 스팸 햄 메일 중 어떤거?
\n", 98 | "회귀: 일주일간 온도가 이랬는데 내일 온도는? 연속성" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": { 104 | "id": "wVGZ9Rphw4gA", 105 | "colab_type": "text" 106 | }, 107 | "source": [ 108 | "Mnist 예제로 학습해보기" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "metadata": { 114 | "id": "PzZxm-0a2mYT", 115 | "colab_type": "code", 116 | "colab": {} 117 | }, 118 | "source": [ 119 | "import numpy as np\n", 120 | "from keras import datasets\n", 121 | "from keras.utils import np_utils\n", 122 | "from keras import layers,models\n", 123 | "import matplotlib.pyplot as plt\n", 124 | "\n", 125 | "from collections import defaultdict\n", 126 | "\n", 127 | "\n", 128 | "#이곳은 하이퍼파라미터를 설정하는 곳 입니다.\n", 129 | "HPARAMS = defaultdict(\n", 130 | " loss='categorical_crossentropy',\n", 131 | " optimizer='adam',\n", 132 | " metrics='accuracy',\n", 133 | " n_epoch=10,\n", 134 | " batch_size=100,\n", 135 | " validation_split=0.2 \n", 136 | ")\n", 137 | "\n", 138 | "hparams = type('', (object,), HPARAMS)() # dict to class\n", 139 | "\n", 140 | "class ANN_MNIST(models.Sequential):\n", 141 | " def __init__(self,Nin,Nh,Nout):\n", 142 | " super().__init__()\n", 143 | " self.add(layers.Dense(Nh,activation='relu',input_shape=(Nin,)))\n", 144 | " self.add(layers.Dense(Nout,activation='softmax'))\n", 145 | " self.compile(loss=hparams.loss,optimizer=hparams.optimizer,metrics=[hparams.metrics])\n", 146 | " \n", 147 | "def one_hot(X_test,Y_test): \n", 148 | " X_test=np_utils.to_categorical(X_test)\n", 149 | " Y_test=np_utils.to_categorical(Y_test)\n", 150 | " \n", 151 | " return X_test,Y_test\n", 152 | "\n", 153 | "def make_2d(X_train,X_test):\n", 154 | " L,H,W=X_train.shape\n", 155 | " X_train=X_train.reshape(-1, H*W)\n", 156 | " X_test=X_test.reshape(-1, H*W)\n", 157 | " \n", 158 | " X_train=X_train/255.0\n", 159 | " X_test=X_test/255.0\n", 160 | " \n", 161 | " \n", 162 | " return X_train,X_test\n", 163 | "\n", 164 | "def data_load():\n", 165 | " (X_train,Y_train),(X_test,Y_test)=datasets.mnist.load_data()\n", 166 | " \n", 167 | " Y_train,Y_test=one_hot(Y_train,Y_test)\n", 168 | " \n", 169 | " X_train,X_test=make_2d(X_train,X_test)\n", 170 | " \n", 171 | " return (X_train, X_test, Y_train, Y_test)\n", 172 | "\n", 173 | "def plot_loss(history):\n", 174 | " plt.plot(history.history['loss'])\n", 175 | " plt.plot(history.history['val_loss'])\n", 176 | " plt.title('Model Loss')\n", 177 | " plt.ylabel('Loss')\n", 178 | " plt.xlabel('Epoch')\n", 179 | " plt.legend(['Train','Test'],loc=0) #두선의 이름 표시\n", 180 | "\n", 181 | "def plot_acc(history):\n", 182 | " plt.plot(history.history['acc'])\n", 183 | " plt.plot(history.history['val_acc'])\n", 184 | " plt.title('Model Accuracy')\n", 185 | " plt.ylabel('Accuracy')\n", 186 | " plt.xlabel('Epoch')\n", 187 | " plt.legend(['Train','Test'],loc=0)\n", 188 | " \n", 189 | "def main():\n", 190 | " Nin=784\n", 191 | " Nh=100\n", 192 | " Nout=10\n", 193 | " \n", 194 | " (X_train,X_test,Y_train,Y_test)=data_load()\n", 195 | " \n", 196 | " \n", 197 | " model=ANN_MNIST(Nin,Nh,Nout)\n", 198 | " \n", 199 | " history= model.fit(X_train,Y_train,epochs=hparams.n_epoch,batch_size=hparams.batch_size,validation_split=hparams.validation_split)\n", 200 | " performance_test=model.evaluate(X_test,Y_test,batch_size=hparams.batch_size)\n", 201 | " print('Test Loss and Accuracy -> ',performance_test)\n", 202 | " \n", 203 | " plot_loss(history)\n", 204 | " plt.show()\n", 205 | " \n", 206 | "\n", 207 | "if __name__ == '__main__':\n", 208 | " main()\n" 209 | ], 210 | "execution_count": 0, 211 | "outputs": [] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": { 216 | "id": "Dazk67NjLjsi", 217 | "colab_type": "text" 218 | }, 219 | "source": [ 220 | "회귀 문제를 이제 풀어보자\n", 221 | "보스턴 집값 문제\n", 222 | "\n" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "metadata": { 228 | "id": "HtxycgkmLu3W", 229 | "colab_type": "code", 230 | "colab": {} 231 | }, 232 | "source": [ 233 | "from keras import layers,models\n", 234 | "from keras import datasets\n", 235 | "from sklearn import preprocessing\n", 236 | "\n", 237 | "class ANN(models.Model):\n", 238 | " def __init__(self,Nin,Nh,Nout):\n", 239 | " hidden=layers.Dense(Nh)\n", 240 | " output=layers.Dense(Nout)\n", 241 | " relu=layers.Activation('relu')\n", 242 | " \n", 243 | " \n", 244 | " #연결 정의\n", 245 | " x=layers.Input(shape=(Nin,))\n", 246 | " h=relu(hidden(x))\n", 247 | " y=output(h)\n", 248 | " \n", 249 | " super().__init__(x,y)\n", 250 | " \n", 251 | " self.compile(loss='mse',optimizer='sgd')\n", 252 | "\n", 253 | "def data_load():\n", 254 | " (X_train,y_train),(X_test,y_test)=datasets.boston_housing.load_data()\n", 255 | " scaler=preprocessing.MinMaxScaler()\n", 256 | " X_train=scaler.fit_transform(X_train)\n", 257 | " X_test=scaler.fit_transform(X_test)\n", 258 | " \n", 259 | " return X_train,y_train,X_test,y_test\n", 260 | "\n", 261 | "def main():\n", 262 | " Nin=13\n", 263 | " Nh=5\n", 264 | " Nout=1\n", 265 | " \n", 266 | " X_train,y_train,X_test,y_test=data_load()\n", 267 | " \n", 268 | " model=ANN(Nin,Nh,Nout)\n", 269 | " history=model.fit(X_train,y_train,epochs=100,batch_size=100,validation_split=0.2,verbose=2)\n", 270 | " \n", 271 | " \n", 272 | " performance_test=model.evaluate(X_test,y_test,batch_size=100)\n", 273 | " print('Test Loss -> {:.2f}'.format(performance_test))\n", 274 | "\n", 275 | "\n", 276 | "if __name__ == '__main__':\n", 277 | " main()\n", 278 | " " 279 | ], 280 | "execution_count": 0, 281 | "outputs": [] 282 | }, 283 | { 284 | "cell_type": "markdown", 285 | "metadata": { 286 | "id": "OewLNY_SP9j3", 287 | "colab_type": "text" 288 | }, 289 | "source": [ 290 | "ANN을 지나 이제 DNN을 배워보자\n", 291 | "ANN은 은닉의 출력이 출력의 입력으로\n", 292 | "DNN은 은닉의 출력이 새로운 은닉의 입력으로\n", 293 | "단지 그 차이일 뿐......." 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "metadata": { 299 | "id": "f4moCWPIQAze", 300 | "colab_type": "code", 301 | "colab": {} 302 | }, 303 | "source": [ 304 | "from keras import layers,models\n", 305 | "from keras import datasets\n", 306 | "from keras.utils import np_utils\n", 307 | "\n", 308 | "from collections import defaultdict\n", 309 | "import numpy as np\n", 310 | "\n", 311 | "\n", 312 | "\n", 313 | "#이곳은 하이퍼파라미터를 설정하는 곳 입니다.\n", 314 | "HPARAMS = defaultdict(\n", 315 | " loss='categorical_crossentropy',\n", 316 | " optimizer='adam',\n", 317 | " metrics='accuracy',\n", 318 | " n_epoch=10,\n", 319 | " batch_size=100,\n", 320 | " validation_split=0.2 \n", 321 | ")\n", 322 | "\n", 323 | "hparams = type('', (object,), HPARAMS)() # dict to class\n", 324 | "\n", 325 | "\n", 326 | "class DNN(models.Sequential):\n", 327 | " def __init__(self,Nin,Nh_1,Nout):\n", 328 | " super().__init__()\n", 329 | " \n", 330 | " #입력 계층의 정의는 첫번째 hidden을 정의할 때 같이 이루어지게 된다.\n", 331 | " self.add(layers.Dense(Nh_1[0],activation='relu',input_shape=(Nin,),name='Hidden-1'))\n", 332 | " self.add(layers.Dropout(0.2))\n", 333 | " \n", 334 | " #제2계층부터는 케라스가 자동으로 현재 계층의 입력 노드 수를 앞에 나온 은닉계층의 출력 수로 설정해준다.\n", 335 | " self.add(layers.Dense(Nh_1[1],activation='relu',name='Hidden-2'))\n", 336 | " self.add(layers.Dropout(0.2))\n", 337 | " self.add(layers.Dense(Nout,activation='softmax'))\n", 338 | " \n", 339 | " self.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])\n", 340 | "\n", 341 | "\n", 342 | "def one_hot(X_test,Y_test): \n", 343 | " X_test=np_utils.to_categorical(X_test)\n", 344 | " Y_test=np_utils.to_categorical(Y_test)\n", 345 | " \n", 346 | " return X_test,Y_test\n", 347 | "\n", 348 | "def make_2d(X_train,X_test):\n", 349 | " L,H,W=X_train.shape\n", 350 | " X_train=X_train.reshape(-1, H*W)\n", 351 | " X_test=X_test.reshape(-1, H*W)\n", 352 | " \n", 353 | " X_train=X_train/255.0\n", 354 | " X_test=X_test/255.0\n", 355 | " \n", 356 | " \n", 357 | " return X_train,X_test\n", 358 | "\n", 359 | "def data_load():\n", 360 | " (X_train,Y_train),(X_test,Y_test)=datasets.mnist.load_data()\n", 361 | " \n", 362 | " Y_train,Y_test=one_hot(Y_train,Y_test)\n", 363 | " \n", 364 | " X_train,X_test=make_2d(X_train,X_test)\n", 365 | " \n", 366 | " return (X_train, X_test, Y_train, Y_test) \n", 367 | " \n", 368 | "def main():\n", 369 | " #기본 파라미터 설정\n", 370 | " Nin=784\n", 371 | " Nh_1=[100,50] #2개의 은닉층\n", 372 | " Nout=10\n", 373 | " \n", 374 | " (X_train,X_test,Y_train,Y_test)=data_load()\n", 375 | " \n", 376 | " model=DNN(Nin,Nh_1,Nout)\n", 377 | " \n", 378 | " history= model.fit(X_train,Y_train,epochs=hparams.n_epoch,batch_size=hparams.batch_size,validation_split=hparams.validation_split)\n", 379 | " performance_test=model.evaluate(X_test,Y_test,batch_size=hparams.batch_size)\n", 380 | " print('Test Loss and Accuracy -> ',performance_test)\n", 381 | " \n", 382 | " plot_loss(history)\n", 383 | " plt.show()\n", 384 | " \n", 385 | "\n", 386 | "if __name__ == '__main__':\n", 387 | " main()\n" 388 | ], 389 | "execution_count": 0, 390 | "outputs": [] 391 | }, 392 | { 393 | "cell_type": "markdown", 394 | "metadata": { 395 | "id": "Q-SbpP49Tmk5", 396 | "colab_type": "text" 397 | }, 398 | "source": [ 399 | "이번에는 컬러 이미지를 분류해보자.\n", 400 | "RGB이니깐 32 * 32 * 3 이다.\n" 401 | ] 402 | }, 403 | { 404 | "cell_type": "code", 405 | "metadata": { 406 | "id": "50qDycoyTpG1", 407 | "colab_type": "code", 408 | "colab": {} 409 | }, 410 | "source": [ 411 | "from keras import layers,models\n", 412 | "from keras import datasets\n", 413 | "from keras.utils import np_utils\n", 414 | "import numpy as np\n", 415 | " \n", 416 | "from collections import defaultdict\n", 417 | "import numpy as np\n", 418 | "\n", 419 | "#이곳은 하이퍼파라미터를 설정하는 곳 입니다.\n", 420 | "HPARAMS = defaultdict(\n", 421 | " loss='categorical_crossentropy',\n", 422 | " optimizer='adam',\n", 423 | " metrics='accuracy',\n", 424 | " n_epoch=10,\n", 425 | " batch_size=100,\n", 426 | " validation_split=0.2 \n", 427 | ")\n", 428 | "\n", 429 | "hparams = type('', (object,), HPARAMS)() # dict to class\n", 430 | "\n", 431 | "\n", 432 | "class DNN(models.Sequential):\n", 433 | " def __init__(self,Nin,Nh_1,pd_l,Nout):\n", 434 | " super().__init__()\n", 435 | " \n", 436 | " #입력 계층의 정의는 첫번째 hidden을 정의할 때 같이 이루어지게 된다.\n", 437 | " self.add(layers.Dense(Nh_1[0],activation='relu',input_shape=(Nin,),name='Hidden-1'))\n", 438 | " self.add(layers.Dropout(pd_l[0]))\n", 439 | " \n", 440 | " #제2계층부터는 케라스가 자동으로 현재 계층의 입력 노드 수를 앞에 나온 은닉계층의 출력 수로 설정해준다.\n", 441 | " self.add(layers.Dense(Nh_1[1],activation='relu',name='Hidden-2'))\n", 442 | " self.add(layers.Dropout(pd_l[1]))\n", 443 | "\n", 444 | " self.add(layers.Dense(Nout,activation='softmax'))\n", 445 | " \n", 446 | " self.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])\n", 447 | "\n", 448 | "\n", 449 | "def data_load():\n", 450 | " (X_train,y_train),(X_test,y_test)=datasets.cifar10.load_data()\n", 451 | "\n", 452 | " Y_train=np_utils.to_categorical(y_train)\n", 453 | " y_test=np_utils.to_categorical(y_test)\n", 454 | " \n", 455 | " L,W,H,C=X_train.shape #50000 32 32 3\n", 456 | " #print(L,H,H,C)\n", 457 | " X_train=X_train.reshape(-1,W*H*C)\n", 458 | " X_test=X_test.reshape(-1,W*H*C)\n", 459 | "\n", 460 | " return (X_train,X_test,Y_train,Y_test)\n", 461 | "\n", 462 | "def main():\n", 463 | " #기본 파라미터 설정\n", 464 | " Nh_1=[100,50] #2개의 은닉층\n", 465 | " pd_l=[0.0,0.0]\n", 466 | " Nout=10\n", 467 | " \n", 468 | " (X_train,X_test,Y_train,Y_test)=data_load()\n", 469 | " \n", 470 | " model=DNN(X_train.shape[1],Nh_1,pd_l,Nout) #입력, 은닉개수,드롭아웃 비율, 출력\n", 471 | " \n", 472 | " history= model.fit(X_train,Y_train,epochs=hparams.n_epoch,batch_size=hparams.batch_size,validation_split=hparams.validation_split)\n", 473 | " performance_test=model.evaluate(X_test,Y_test,batch_size=hparams.batch_size)\n", 474 | " print('Test Loss and Accuracy -> ',performance_test)\n", 475 | " \n", 476 | " \n", 477 | "\n", 478 | "if __name__ == '__main__':\n", 479 | " main()\n" 480 | ], 481 | "execution_count": 0, 482 | "outputs": [] 483 | }, 484 | { 485 | "cell_type": "markdown", 486 | "metadata": { 487 | "id": "kXrZtbBzXHja", 488 | "colab_type": "text" 489 | }, 490 | "source": [ 491 | "이제는 CNN입니다." 492 | ] 493 | }, 494 | { 495 | "cell_type": "code", 496 | "metadata": { 497 | "id": "pYA0hNXsa6uh", 498 | "colab_type": "code", 499 | "colab": {} 500 | }, 501 | "source": [ 502 | "from keras import layers,models\n", 503 | "from keras import datasets\n", 504 | "from keras.utils import np_utils\n", 505 | "from keras import backend\n", 506 | "import keras\n", 507 | "from collections import defaultdict\n", 508 | "import numpy as np\n", 509 | "\n", 510 | "\n", 511 | "\n", 512 | "\n", 513 | "class CNN(models.Sequential):\n", 514 | " def __init__(self,input_shape,num_classes):\n", 515 | " super().__init__()\n", 516 | " \n", 517 | " self.add(layers.Conv2D(32,kernel_size=(3,3),activation='relu',input_shape=input_shape)) #커널개수, 커널사이즈, 활성화함수, 입력 \n", 518 | " self.add(layers.Conv2D(64,(3,3),activation='relu'))\n", 519 | " self.add(layers.MaxPooling2D(pool_size=(2,2))) #2x2 셀로 묶어서 가장 큰값을 내보낸다.\n", 520 | " self.add(layers.Dropout(0.25))\n", 521 | " \n", 522 | " self.add(layers.Flatten())#완전연결 계층으로 들어간다.\n", 523 | " \n", 524 | " self.add(layers.Dense(128,activation='relu')) #은닉 계층은 길이가 128로\n", 525 | " self.add(layers.Dropout(0.5))\n", 526 | " self.add(layers.Dense(num_classes,activation='softmax'))\n", 527 | " \n", 528 | " self.compile(loss=keras.losses.categorical_crossentropy,optimizer='rmsprop',metrics=['accuracy'])\n", 529 | " \n", 530 | "\n", 531 | "class DATA():\n", 532 | " def __init__(self):\n", 533 | " num_classes=10\n", 534 | " (x_train,y_train),(x_test,y_test)=datasets.mnist.load_data()\n", 535 | " print(x_train.shape) #60000,784 (원래)\n", 536 | " \n", 537 | " #img_rows,img_cols=X_train.shape[1:]\n", 538 | " img_rows,img_cols=int(28),int(28) \n", 539 | " print(img_rows,img_cols)\n", 540 | " \n", 541 | " if backend.image_data_format()=='channels_first':\n", 542 | " x_train=x_train.reshape(x_train.shape[0],1,img_rows,img_cols)\n", 543 | " x_test=x_test.reshape(x_test.shape[0],1,img_rows,img_cols)\n", 544 | " input_shape=(1,img_rows,img_cols) #컬러 채널을 임의로 첫번째로 해준다.\n", 545 | " else:\n", 546 | " x_train=x_train.reshape(x_train.shape[0],img_rows,img_cols,1)\n", 547 | " x_test=x_test.reshape(x_test.shape[0],img_rows,img_cols,1)\n", 548 | " input_shape=(img_rows,img_cols,1) #마지막에 컬러 채널을 임의로 첫번째로 해준다.\n", 549 | " \n", 550 | " \n", 551 | " x_train=x_train.astype('float32')\n", 552 | " x_test=x_test.astype('float32')\n", 553 | " x_train/=255\n", 554 | " x_test/=255\n", 555 | " \n", 556 | " y_train=keras.utils.to_categorical(y_train,num_classes)\n", 557 | " y_test=keras.utils.to_categorical(y_test,num_classes)\n", 558 | " \n", 559 | " \n", 560 | " self.input_shape=input_shape\n", 561 | " self.num_classes=num_classes\n", 562 | " \n", 563 | " self.x_train,self.y_train=x_train,y_train\n", 564 | " self.x_test,self.y_test=x_test,y_test\n", 565 | " \n", 566 | " \n", 567 | "\n", 568 | "def main():\n", 569 | " batch_size=128\n", 570 | " epochs=10\n", 571 | " \n", 572 | " data=DATA()\n", 573 | " model=CNN(data.input_shape,data.num_classes)\n", 574 | " \n", 575 | " history= model.fit(data.x_train,data.y_train,batch_size=batch_size,epochs=epochs,validation_split=0.2)\n", 576 | " \n", 577 | " score=model.evaluate(data.x_test,data.y_test)\n", 578 | " print()\n", 579 | " print('Test Loss',score[0])\n", 580 | " print('Test Accuracy',score[1])\n", 581 | " \n", 582 | "\n", 583 | "if __name__ == '__main__':\n", 584 | " main()\n" 585 | ], 586 | "execution_count": 0, 587 | "outputs": [] 588 | } 589 | ] 590 | } -------------------------------------------------------------------------------- /Pytorch_Basic_Tutorial_Chanjun_Park.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Pytorch_Basic_Tutorial_Chanjun_Park.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [] 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "accelerator": "GPU" 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "code", 19 | "metadata": { 20 | "id": "yR0heznQs5yD", 21 | "colab_type": "code", 22 | "outputId": "93860b64-0576-4cf8-dc76-7313394337c3", 23 | "colab": { 24 | "base_uri": "https://localhost:8080/", 25 | "height": 87 26 | } 27 | }, 28 | "source": [ 29 | "import torch\n", 30 | "\n", 31 | "cpu_tensor=torch.zeros(4,3) #3개짜리 4개\n", 32 | "device=torch.device(\"cuda:0\") #device 선언\n", 33 | "gpu_tensor=cpu_tensor.to(device)\n", 34 | "print(gpu_tensor)" 35 | ], 36 | "execution_count": 1, 37 | "outputs": [ 38 | { 39 | "output_type": "stream", 40 | "text": [ 41 | "tensor([[0., 0., 0.],\n", 42 | " [0., 0., 0.],\n", 43 | " [0., 0., 0.],\n", 44 | " [0., 0., 0.]], device='cuda:0')\n" 45 | ], 46 | "name": "stdout" 47 | } 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": { 53 | "id": "HcWh_pipveFn", 54 | "colab_type": "text" 55 | }, 56 | "source": [ 57 | "선형 회귀분석\n", 58 | "\n", 59 | "주어진 데이터를 가장 잘 설명하는 직선 하나를 찾는 것.\n", 60 | "\n", 61 | "어떻게? => 예측 값과 실제 결과값의 차이를 최소화 하는 방향으로 !\n", 62 | "\n", 63 | "예측값과 실제 결과값의 차이 => LOSS,COST (손실함수, 비용함수)\n", 64 | "\n", 65 | "MSE == L2 Loss\n", 66 | "\n", 67 | "최소화 하는 방향? => Optimization\n", 68 | "\n", 69 | "대표적으로 경사하강법\n", 70 | "\n", 71 | "경사란 결국 기울기, 기울기란 결국 미분 값, \n", 72 | "\n", 73 | "얼마만큼 최소화 할래? => Learning Rate" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": { 79 | "id": "DXFEC9aAwx0Y", 80 | "colab_type": "text" 81 | }, 82 | "source": [ 83 | "Pytorch 결국 연산그래프를 만들고 경사를 계산하는 방식\n", 84 | "\n", 85 | "데이터는 Tensor를 사용.\n", 86 | "\n", 87 | "Tensor는 다차원 배열이라고 정의할 수 있음.\n", 88 | "\n", 89 | "\n" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "metadata": { 95 | "id": "klyfb1y7vZeR", 96 | "colab_type": "code", 97 | "colab": {} 98 | }, 99 | "source": [ 100 | "import torch\n", 101 | "\n", 102 | "x=torch.Tensor(2,3) #3개짜리가 2개\n", 103 | "\n", 104 | "print(x)" 105 | ], 106 | "execution_count": 0, 107 | "outputs": [] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "metadata": { 112 | "id": "d3ovWCsoxGGV", 113 | "colab_type": "code", 114 | "colab": {} 115 | }, 116 | "source": [ 117 | "import torch\n", 118 | "\n", 119 | "#data,type,device,requires_grad\n", 120 | "\n", 121 | "x=torch.Tensor([[1,2,3],[1,3,2]])\n", 122 | "\n", 123 | "print(x)\n", 124 | "print(x.shape)\n", 125 | "\n", 126 | "#torch.XX\n", 127 | "#torch.cuda.XX\n", 128 | "#XX => FloatTensor, DoubleTensor, IntTensor\n", 129 | "#device는 텐서를 어느 기기에 올릴 것인지를 명시함.\n", 130 | "#requires_grad는 이 텐서에 대한 기울기를 저장할지 여부를 결정\n", 131 | "\n", 132 | "x_tensor=torch.tensor(data=[2.0,3.0],requires_grad=True)\n", 133 | "print(x_tensor)\n", 134 | "\n" 135 | ], 136 | "execution_count": 0, 137 | "outputs": [] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "metadata": { 142 | "id": "Sc3FRT4kyh_V", 143 | "colab_type": "code", 144 | "colab": {} 145 | }, 146 | "source": [ 147 | "import torch\n", 148 | "\n", 149 | "x=torch.tensor(data=[2.0,3.0],requires_grad=True)\n", 150 | "z=2*(x**2)+3 #연산 그래프\n", 151 | "\n", 152 | "target=torch.Tensor([3.0,4.0])\n", 153 | "\n", 154 | "print(z)\n", 155 | "print(z-target)\n", 156 | "print(abs(z-target))\n", 157 | "print(torch.abs(z-target))\n", 158 | "print(torch.sum(torch.abs(z-target)))\n", 159 | "\n", 160 | "loss=torch.sum(torch.abs(z-target))\n", 161 | "\n", 162 | "loss.backward()\n", 163 | "\n", 164 | "print(x.grad,z.grad)" 165 | ], 166 | "execution_count": 0, 167 | "outputs": [] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "metadata": { 172 | "id": "iPKHZMG405fd", 173 | "colab_type": "code", 174 | "colab": {} 175 | }, 176 | "source": [ 177 | "import torch\n", 178 | "import torch.nn as nn \n", 179 | "import torch.optim as optim #경사하강법\n", 180 | "import torch.nn.init as init #텐서에 초기값을 주기 위한..\n", 181 | "\n", 182 | "num_data=1000\n", 183 | "num_epoch=500\n", 184 | "\n", 185 | "\n", 186 | "x=init.uniform_(torch.Tensor(num_data,1),-10,10)#-10부터 10까지 균등하게(uniform)하게 초기화\n", 187 | "noise=init.normal_(torch.FloatTensor(num_data,1),std=1) #노이즈, 현실성 반영, 표준 정규분포를 따르는 노이즈 = 가우시안 노이즈 , mean(평균)=0, std(표준편차)=1\n", 188 | "\n", 189 | "y=2*x+3\n", 190 | "y_noise=2*(x+noise)+3 \n", 191 | "\n", 192 | "model=nn.Linear(1,1) #들어오는 특성의 수, 결과로 나오는 특성의 수 \n", 193 | "loss_func=nn.L1Loss() #차이의 절대값의 평균\n", 194 | "\n", 195 | "optimizer=optim.SGD(model.parameters(),lr=0.01)\n", 196 | "\n", 197 | "label=y_noise\n", 198 | "\n", 199 | "for i in range(num_epoch):\n", 200 | " optimizer.zero_grad() #기울기 0으로 초기화 , 기울기를 초기화 해야 새로운 가중치와 편차에 대해서 새로운 기울기를 구할 수 있음.\n", 201 | " output=model(x)\n", 202 | " \n", 203 | " loss=loss_func(output,label)\n", 204 | " loss.backward() #각 변수 즉 w,b에 대한 기울기가 계산됨.\n", 205 | " \n", 206 | " optimizer.step() #업데이트 \n", 207 | " \n", 208 | " if i%10==0:\n", 209 | " print(loss.data)\n", 210 | " param_list=list(model.parameters())\n", 211 | " print(param_list[0].item(), param_list[1].item())\n", 212 | " \n", 213 | "\n" 214 | ], 215 | "execution_count": 0, 216 | "outputs": [] 217 | }, 218 | { 219 | "cell_type": "markdown", 220 | "metadata": { 221 | "id": "4Fn2oyfzyWkm", 222 | "colab_type": "text" 223 | }, 224 | "source": [ 225 | "여러 입력이 들어모면 각각 가중치를 곱해주고 편차도 더해준다.\n", 226 | "\n", 227 | "이렇게 다 더한 값을 활성화 함수를 통해 변형하여 전달하는 단위를 인공뉴런이라고 한다.\n", 228 | "\n", 229 | "인공신경망은 입력층, 은닉층, 출력층으로 이루어짐.\n", 230 | "\n", 231 | "딥러닝 즉 심층 신경망은 은닉층이 2개이상인 것을 의미한다.\n", 232 | "\n" 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "metadata": { 238 | "id": "wFy6nnxnyC8k", 239 | "colab_type": "code", 240 | "colab": {} 241 | }, 242 | "source": [ 243 | "import torch\n", 244 | "import torch.nn as nn\n", 245 | "import torch.optim as optim\n", 246 | "import torch.nn.init as init\n", 247 | "\n", 248 | "\n", 249 | "num_data=1000\n", 250 | "num_epochs=10000\n", 251 | "\n", 252 | "\n", 253 | "noise=init.normal_(torch.FloatTensor(num_data,1),std=1) #노이즈 더하기 , 모양은 x와 동일해야 \n", 254 | "\n", 255 | "x=init.uniform_(torch.Tensor(num_data,1),-15,15) #균등분포 초기화 \n", 256 | "\n", 257 | "y=(x**2)+3 #목적함수\n", 258 | "\n", 259 | "y_noise=y+noise #목적 함수 즉 목표\n", 260 | "\n", 261 | "model=nn.Sequential(\n", 262 | " nn.Linear(1,6),\n", 263 | " nn.ReLU(),\n", 264 | " nn.Linear(6,10),\n", 265 | " nn.ReLU(),\n", 266 | " nn.Linear(10,6),\n", 267 | " nn.ReLU(),\n", 268 | " nn.Linear(6,1)\n", 269 | ")\n", 270 | "\n", 271 | "loss_func=nn.L1Loss() #Loss는 L1 Loss를 이용한다.\n", 272 | "\n", 273 | "optimizer=optim.SGD(model.parameters(),lr=0.0002) #옵티마이저는 SGD를 이용\n", 274 | "\n", 275 | "loss_array=[] #loss 담기 위한\n", 276 | "\n", 277 | "for i in range(num_epochs):\n", 278 | " optimizer.zero_grad()\n", 279 | " output=model(x) #forward 과정 , 즉 값을 예측\n", 280 | " loss=loss_func(output,y_noise) #예측값과 목표값의 loss 계산\n", 281 | " loss.backward() #미분 진행, 즉 기울기 계산 진행\n", 282 | " optimizer.step() #학습 진행 \n", 283 | " \n", 284 | " loss_array.append(loss)\n", 285 | " \n", 286 | "import matplotlib.pyplot as plt\n", 287 | "\n", 288 | "plt.plot(loss_array)\n", 289 | "plt.show()\n" 290 | ], 291 | "execution_count": 0, 292 | "outputs": [] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": { 297 | "id": "kjMAktJ-7Sjt", 298 | "colab_type": "text" 299 | }, 300 | "source": [ 301 | "CNN이란 국소적인 영역을 보고 단순한 패턴에 자극을 받는 단순세포와 넓은 영역을 보고 복잡한 패턴에 작그을 받는 복잡세포가 레이어를 이루고 있다.\n", 302 | "\n", 303 | "필터 = 커널\n", 304 | "\n", 305 | "하나의 필터에 대해 이미지를 쭉 지나가면서 이미지의 부분 부분이 필터와 얼마나 일치하는지를 계산한다.\n", 306 | "\n", 307 | "이동의 단위는 stride이다.\n", 308 | "\n", 309 | "하나의 이미지에 대하여 여러개의 필터를 적용할 수 있다.\n", 310 | "\n", 311 | "필터 하나당 입력 이미지 전체에 대한 필터의 일치정도가 나오는데 이를 활성화 지도, 특성지도라고 한다.\n", 312 | "\n", 313 | "활성화 지도의 크기는 입력이미지와, 필터의 크기, 스트라이드에 크기에 따라서 결정이 된다.\n", 314 | "\n", 315 | "floor((입력크기-커널크기/스트라이드크기)+1 )\n", 316 | "\n", 317 | "문제는 입력이미지에 필터를 계속 적용하다보면 크기가 줄어듬....\n", 318 | "\n", 319 | "이렇게 되면 인공신경망 입장에서는 은닉층의 개수에 제한이 생기는 것과 같고 결과적으로 복잡한 패턴을 학습할 수가 없게 됨.\n", 320 | "\n", 321 | "따라서 패팅이라는 기법이 등장하게 됨.\n", 322 | "\n", 323 | "패딩이란 일정한 크기의 층으로 이미지를 감싸는 것을 의미한다.\n", 324 | "\n", 325 | "9x9에 패딩 1을 주면 11x11로 변하게 됨.\n", 326 | " \n", 327 | "네 방향 테두리를 쭉 돌아가면서 패팅을 적용하기 때문에 이미지 크기는 1이 아니라 2가 늘어나게 됨.\n", 328 | "\n", 329 | "floor((입력크기-커널크기+(2*패딩의크기)/스트라이드크기)+1 )\n", 330 | "\n", 331 | "\n", 332 | "반대로 입력 이미지가 엄청나게 크다면 굳이 패딩이 필요없음,, 여전히 클 것이기에...\n", 333 | "\n", 334 | "이럴 때 풀링이라는 것을 사용함.\n", 335 | "\n", 336 | "풀링은 다운 샘플링 또는 서브 샘플링에 일종이며 맥스풀링과 평균 풀링이 있음.\n", 337 | "\n", 338 | "풀링의 범위가 2X2라면 한번에 2칸씩 이동...\n", 339 | "\n", 340 | "결론적으로 대게 몇번의 합성곱 연산을 활성화 함수와 함께 적용한 이후 풀링으로 전체 크기를 줄여주는 과정을 반복함.\n" 341 | ] 342 | }, 343 | { 344 | "cell_type": "markdown", 345 | "metadata": { 346 | "id": "DYYn1eyYCAwz", 347 | "colab_type": "text" 348 | }, 349 | "source": [ 350 | "분류 문제에서는 여러 클래스가 있음.\n", 351 | "\n", 352 | "정답은 원 핫 인코딩으로 변환.\n", 353 | "\n", 354 | "원핫 인코딩은 본래의 정답을 확률 분포로 변환해 주는 것.\n", 355 | "\n", 356 | "즉 정답에 해당하는 확률은 1 아니면 0\n", 357 | "\n", 358 | "신경망의 결과값과 정답을 비교해야 하니 신경망의 결과값도 확률의 형태여야\n", 359 | "\n", 360 | "이래서 등장한 것이 소프트 맥스\n", 361 | "\n", 362 | "소프트맥스란 결과값을 확률로 바꾸어주는 역할.\n", 363 | "\n", 364 | "결과값 벡터에 있는 값들이 지수함수를 통과하면 모든 값이 양수로 되는 효과가 있음. 따라서 소프트 맥스 함수에 exp가 있는 것.\n", 365 | "\n", 366 | "그렇다면 두개의 확률벡터는 어떤 기준으로 손실(LOSS)를 측정할 까?\n", 367 | "\n", 368 | "L1 => 절대값 거리를 기준\n", 369 | "L2 => 차이의 제곱을 기준으로 하는 평균제곱오차\n", 370 | "\n", 371 | "교차앤트로피 : 목표로하는 최적의 확률분포 p와 이를 근사하려는 확류분포 q가 얼마나 다른지를 측정하는 방법\n", 372 | "\n", 373 | "교차앤트로피는 예측이 잘못될 수록 L!손실보다 더 크게 증가.. 그만큼 패널티가 크고 손실값이 크기 때문에 학습면에서 장점 보유, 따라서 분류 문제에서 교차엔트로피 손실 많이 사용\n", 374 | "\n", 375 | "\n", 376 | "하이퍼파라미터: 학습의 대상이 아니라 학습 이전에 정해놓은 변수" 377 | ] 378 | }, 379 | { 380 | "cell_type": "markdown", 381 | "metadata": { 382 | "id": "BWDwXSzwY57n", 383 | "colab_type": "text" 384 | }, 385 | "source": [ 386 | "CNN - MNIST 분류" 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "metadata": { 392 | "id": "Ne2XKnBl7Ers", 393 | "colab_type": "code", 394 | "colab": {} 395 | }, 396 | "source": [ 397 | "import torch\n", 398 | "import torch.nn as nn\n", 399 | "import torch.optim as optim\n", 400 | "import torch.nn.init as init\n", 401 | "import torchvision.datasets as dset\n", 402 | "import torchvision.transforms as transforms\n", 403 | "from torch.utils.data import DataLoader #데이터를 하나씩 전달하지 않고 원하는 배치사이즈대로 묶어서 전달하거나 효율적인 학습을 위한 셔플링 등을 여기서 해줌\n", 404 | "\n", 405 | "batch_size=256\n", 406 | "learning_rate=0.0002\n", 407 | "num_epochs=10\n", 408 | "\n", 409 | "\n", 410 | "#transform과 target_transform은 각각 데이터와 라벨에 대한 변형을 의미한다.\n", 411 | "#여기서는 transform은 단순히 텐서로 변환... 라벨에 대한 변환은 안함.\n", 412 | "#num_workes: 데이터를 묶을 때 프로세스 개수\n", 413 | "#drop_last: 묶고 남는 데이터는 버릴지 여부\n", 414 | "#train_loader와 test_loader는 순차적으로 모델에 데이터를 전달해준다.\n", 415 | "mnist_train=dset.MNIST(\"./\",train=True,transform=transforms.ToTensor(),target_transform=None,download=True) #학습 데이터\n", 416 | "mnist_test=dset.MNIST(\"./\",train=False,transform=transforms.ToTensor(),target_transform=None,download=True) #테스트 데이터\n", 417 | "\n", 418 | "train_loader=torch.utils.data.DataLoader(mnist_train,batch_size=batch_size,shuffle=True,num_workers=2,drop_last=True)\n", 419 | "test_loader=torch.utils.data.DataLoader(mnist_test,batch_size=batch_size,shuffle=False,num_workers=2,drop_last=True)\n", 420 | "\n", 421 | "\n", 422 | "class CNN(nn.Module):\n", 423 | " \n", 424 | " def __init__(self):\n", 425 | " super(CNN,self).__init__() #CNN클래스의 부모 클래스인 nn.Module을 초기화 하는 역할.\n", 426 | " \n", 427 | " #합성곱 연산\n", 428 | " self.layer=nn.Sequential(\n", 429 | " \n", 430 | " #in_channels, out_channels,kernel_size,stride,padding 등이 잇음.\n", 431 | " #in_channels: RGB 3채널 데이터를 입력으로 받았던 것을 예로 들어 설명하면 in_channels는 3\n", 432 | " #out_channels: 필터의 개수\n", 433 | " \n", 434 | " #따라서 입력: [batch_size, in_channels, 가로, 세로]\n", 435 | " #합성곱 연산의 결괴: [batch_size,out_channels,가로,세로]\n", 436 | " #MNIST입력 같은 경우는 [batch_size,1,가로,세로]\n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " nn.Conv2d(1,16,5), # (batch_size,out_channels=필터의 개수=커널의 개수,kernel_size) // (stride =1 padding=0)으로 기본 설정 // 입력으로는 [batch_size,1,28,28]이 들어올 것.\n", 441 | " #위에 conv연산 통과시 [batch_size,16,24,24]가 될 것임. #16인 이유는 필터의 개수, 24는 연산에 따라서..\n", 442 | " nn.ReLU(),\n", 443 | " nn.Conv2d(16,32,5), #[batch_size,32,20,20]이 된다.\n", 444 | " nn.ReLU(),\n", 445 | " nn.MaxPool2d(2,2), #(kernel_size,stride) , 연산후에는 텐서가 반으로 줄어듬. [batch_size,32,10,10] // kernel_size,stride,padding등을 받음. kernel_size는 풀링 연산을 할 때 한번에 훑는 영역의 크기, \n", 446 | " nn.Conv2d(32,64,5), # [batch_size,64,6,6]\n", 447 | " nn.ReLU(),\n", 448 | " nn.MaxPool2d(2,2) # [batch_size,64,3,3]\n", 449 | " )\n", 450 | " \n", 451 | " self.fc_layer=nn.Sequential(\n", 452 | " nn.Linear(64*3*3,100),#batch_size,100\n", 453 | " nn.ReLU(),\n", 454 | " nn.Linear(100,10) #[batch_size,10]\n", 455 | " )\n", 456 | " \n", 457 | " def forward(self,x):\n", 458 | " out=self.layer(x) #convolution and max pooling\n", 459 | " out=out.view(batch_size,-1) #Fully connected 입력을 위하여 ...\n", 460 | " out=self.fc_layer(out)\n", 461 | " return out\n", 462 | " \n", 463 | " \n", 464 | "device=torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", 465 | "model=CNN().to(device)\n", 466 | "loss_func=nn.CrossEntropyLoss()\n", 467 | "optimizer=torch.optim.Adam(model.parameters(),lr=learning_rate)\n", 468 | "\n", 469 | "loss_arr=[]\n", 470 | "\n", 471 | "for i in range(num_epochs):\n", 472 | " for j,[image,label] in enumerate(train_loader):\n", 473 | " x=image.to(device)\n", 474 | " y_=label.to(device)\n", 475 | " \n", 476 | " optimizer.zero_grad()\n", 477 | " output=model.forward(x)\n", 478 | " loss=loss_func(output,y_)\n", 479 | " loss.backward()\n", 480 | " optimizer.step()\n", 481 | " \n", 482 | " if j%1000 ==0:\n", 483 | " print(loss)\n", 484 | " loss_arr.append(loss.cpu().detach().numpy())\n", 485 | " \n", 486 | " \n", 487 | "correct=0\n", 488 | "total=0\n", 489 | "\n", 490 | "with torch.no_grad():\n", 491 | " for image,label in test_loader:\n", 492 | " x=image.to(device)\n", 493 | " y_=label.to(device)\n", 494 | " \n", 495 | " output=model.forward(x)\n", 496 | " _,output_index=torch.max(output,1) #(최대값, 그 인덱스)\n", 497 | " \n", 498 | " total+=label.size(0) #size(0)이것은 배치사이즈에 해당함.\n", 499 | " correct+=(output_index==y_).sum().float()\n", 500 | " print(\"Accuracy of Test Data:{}\".format(100*correct/total))\n" 501 | ], 502 | "execution_count": 0, 503 | "outputs": [] 504 | }, 505 | { 506 | "cell_type": "markdown", 507 | "metadata": { 508 | "id": "az_7F0XsaW8L", 509 | "colab_type": "text" 510 | }, 511 | "source": [ 512 | "RNN" 513 | ] 514 | }, 515 | { 516 | "cell_type": "code", 517 | "metadata": { 518 | "id": "GzyT4cRHQ5V3", 519 | "colab_type": "code", 520 | "colab": {} 521 | }, 522 | "source": [ 523 | "import torch\n", 524 | "import torch.nn as nn\n", 525 | "import torch.optim as optim\n", 526 | "import numpy as np\n", 527 | "\n", 528 | "n_hidden=35 # 순환 신경망 노드 수\n", 529 | "lr=0.01\n", 530 | "epochs=1000\n", 531 | "\n", 532 | "string=\"hello pytorch.how long can rnn cell number\"\n", 533 | "chars=\"abcdefghijklmnopqrstuvwxyz?!.,;:01 \"\n", 534 | "\n", 535 | "char_list=[i for i in chars]\n", 536 | "n_letters=len(char_list)\n", 537 | "\n", 538 | "def string_to_onehot(string):\n", 539 | " start=np.zeros(shape=len(char_list),dtype=int)\n", 540 | " end=np.zeros(shape=len(char_list),dtype=int)\n", 541 | " start[-2]=1\n", 542 | " end[-1]=1\n", 543 | " \n", 544 | " for i in string:\n", 545 | " idx=char_list.index(i)\n", 546 | " zero=np.zeros(shape=n_letters,dtype=int)\n", 547 | " zero[idx]=1\n", 548 | " start=np.vstack([start,zero])\n", 549 | " output=np.vstack([start,end])\n", 550 | " return output\n", 551 | "\n", 552 | "def onehot_to_word(onehot_1):\n", 553 | " onehot=torch.Tensor.numpy(onehot_1)\n", 554 | " return char_list[onehot.argmax()]\n", 555 | "\n", 556 | "\n", 557 | "\n", 558 | "class RNN(nn.Module):\n", 559 | " \n", 560 | " def __init__(self,input_size,hidden_size,output_size):\n", 561 | " super(RNN,self).__init__()\n", 562 | " \n", 563 | " self.input_size=input_size\n", 564 | " self.hidden_size=hidden_size\n", 565 | " self.output_size=output_size\n", 566 | " \n", 567 | " self.i2h=nn.Linear(input_size,hidden_size)\n", 568 | " self.h2h=nn.Linear(hidden_size,hidden_size)\n", 569 | " self.i2o=nn.Linear(hidden_size,output_size)\n", 570 | " self.act_fn=nn.Tanh()\n", 571 | " \n", 572 | " def forward(self,input,hidden):\n", 573 | " hidden=self.act_fn(self.i2h(input)+self.h2h(hidden))\n", 574 | " output=self.i2o(hidden)\n", 575 | " return output,hidden\n", 576 | " def init_hidden(self):\n", 577 | " return torch.zeros(1,self.hidden_size)\n", 578 | " \n", 579 | "rnn=RNN(n_letters,n_hidden,n_letters)\n", 580 | "\n", 581 | "\n", 582 | "loss_func=nn.MSELoss()\n", 583 | "optimizer=torch.optim.Adam(rnn.parameters(),lr=lr)\n", 584 | "\n", 585 | "\n", 586 | "one_hot=torch.from_numpy(string_to_onehot(string)).type_as(torch.FloatTensor())\n", 587 | "print(one_hot.size())#torch.Size([44, 35])\n", 588 | "\n", 589 | "for i in range(epochs):\n", 590 | " rnn.zero_grad()\n", 591 | " total_loss=0\n", 592 | " hidden=rnn.init_hidden()\n", 593 | " \n", 594 | " \n", 595 | " for j in range(one_hot.size()[0]-1): \n", 596 | " input_=one_hot[j:j+1,:] #현재단어\n", 597 | " target=one_hot[j+1] #다음단어 예측\n", 598 | " \n", 599 | " output,hidden=rnn.forward(input_,hidden) #output과 hidden을 받음. \n", 600 | " loss=loss_func(output.view(-1),target.view(-1)) #output과 target에 대한 LOSS\n", 601 | " total_loss+=loss#BPTT\n", 602 | " input_=output #출력을 다시 입력으로 \n", 603 | " total_loss.backward()\n", 604 | " optimizer.step()\n", 605 | " \n", 606 | " if i%10==0:\n", 607 | " print(total_loss)\n", 608 | " \n", 609 | " \n", 610 | "start=torch.zeros(1,len(char_list))\n", 611 | "start[:-2]=1\n", 612 | "\n", 613 | "with torch.no_grad():\n", 614 | " hidden=rnn.init_hidden()\n", 615 | " input_=start\n", 616 | " output_string=\"\"\n", 617 | " \n", 618 | " for i in range(len(string)):\n", 619 | " output,hidden=rnn.forward(input_,hidden)\n", 620 | " output_string+=onehot_to_word(output.data)\n", 621 | " input_=output #output이 그 다음 step 입력으로 들어간다.\n", 622 | " \n", 623 | " print(output_string)" 624 | ], 625 | "execution_count": 0, 626 | "outputs": [] 627 | } 628 | ] 629 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeepLearning_Basic_Tutorial 2 | ## Deep Learning Basic Tutorial (Pytorch, Keras) 3 | 4 | #### Pytorch와 Keras 딥러닝 기초 튜토리얼을 만들어보았습니다. 5 | 6 | #### 딥러닝의 기초 개념부터 (ANN, DNN) CNN, RNN 까지 Pytorch와 Keras 코드로 기초부터 학습해보세요. 7 | 8 | 9 | 참고자료
10 | 3분 Keras
11 | Pytorch 첫걸음 12 | --------------------------------------------------------------------------------