[AIFFEL] 22.Jan.12 - Tensorflow_and_CNN

Deok Jong Moon·2022년 1월 12일
0
post-thumbnail

오늘의 학습 리스트

LMS

  • Backbone 모델이란 무엇일까
    : pre-trained 모델로서 Transfer Learning 시 기초로 삼을 모델(예 : CNN 계열의 VGG, RestNET)

  • Transfer Learning

    • 사전학습 된 모델(pre-trained model) 이용하기
    • 사전학습 된 모델이란, 내가 풀고자 하는 문제와 비슷하면서 사이즈가 큰 데이터로 이미 학습이 되어 있는 모델입니다
  • Transfer Learning을 한다면...

    • 시작은 Convolutional base의 더 깊은 층과 Classifier는 pre-training 시 데이터의 구체적인 특징을 갖고 있으니 없앤다
      1) 전략 1 : 전체 모델을 새로 학습시키기

      • 새로 하는 것이다 보니, 좋은 컴퓨터와 많은 데이터가 필요하다.

      2) 전략 2 : Convolutional base의 일부분은 고정시킨 상태로, 나머지 계층과 classifier를 새로 학습시키기
      3) 전략 3: Convloutional base는 고정시키고, classifier만 새로 학습시키기

      • pre-training 데이터가 내 데이터와 매우 비슷할 때
      • 혹은 내 데이터가 적거나, 컴퓨터가 안 좋을 때 실행
    • 전략 3)과는 다르게 1), 2)는 모델이 학습을 해야 해서 learning-rate를 주의 깊게 설정해야 함

    • learning-rate에 따라 빠르게 진행되면 이전의 학습되어 내장된 것이 다 무용지물이 될 수 있음.

  • matplotlib으로 이미지를 시각화 할 경우에는 모든 픽셀값이 양수여야 하므로, -1~1 사이의 픽셀값이 있다면 1을 더한 후 2로 나눠서 0~1 사이의 값으로 변환해야 한다.

  • Dataset.shuffle(buffer_size).batch(batch_size)의 의미
    1) 데이터셋을 shuffle해야 하는데,
    2) shuffle할 요소 갯수는 buffer_size만큼하고, 그건 데이터셋에서 차례대로 가져와
    3) 그렇게 buffer_size만한 buffer를 가져오면 거기서 batch_size만큼 buffer에서 randomely shuffle해서 보내
    4) 사실 이럴거면 buffer_size가 entire 데이터셋과 같으면 되지 않나 싶지만
    5) 목적은 만약 이 entire 데이터셋이 너무 크면 메모리 소모가 크니까로 보인다.
    7) 맞나...?

  • Tensorflow 데이터셋을 가져올 때
    (raw_train, raw_validation, raw_test), metadata = tfds.load( 'cats_vs_dogs', split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'], with_info=True, as_supervised=True, )
    이렇게 가져오는데, 이건 가져올 때부터 train, validation, test 3개로 나눠서 가져오나보다.

    • 찾아보니 그냥 내 마음인 것 같다.
    • (training_set, validation_set), dataset_info = tfds.load( 'tf_flowers', split=['train[:70%]', 'train[70%:]'], with_info=True, as_supervised=True, )
    • 원하는 만큼, %로 각각 나눠서 split하면 되나보다.
    • shuffle(), batch(), repeat() 등의 활용 의미가 궁금하면(https://deep-deep-deep.tistory.com/27)
    • 참고로 batch()는 shuffle 기능이 없단다.
      : 그래서 shuffle을 원하면 shuffle().batch()로 먼저 해줘야 한다.
  • Global Average Pooling

    • flatten은 그냥 전부 다 1열로 배열하는 거라면
    • Global Average Pooling은 3차원 RGB 데이터로 치면 각각 차원마다 픽셀 값의 평균 값을 요소로서 배열에 넣는 것이다.
    • 즉, (25, 25, 3)이라는 shape이 있다면 (1, 1, 3)으로 되어버린다.(여기에 이미지 갯수까지 하면, (N개, 1, 1, 차원수)
  • 모델 혹은 레이어에 데이터를 넣거나 하는 건 모델명 or 레이어명(데이터명)으로 하면 되는 것 같다.

  • model.compile()의 존재 이유
    : Compile defines the loss function, the optimizer and the metrics. That's all. It has nothing to do with the weights and you can compile a model as many times as you want without causing any problem to pretrained weights.

  • plt.plot(y_values)만 넣어도 plot이 만들어진다.
    : 이유는 이거란다.
    : "As pyplot automatically enumerates these using [0,1,2,3]"

  • Transfer Learning으로 모델 만들기(classifier 부분만 자체 제작이라면)
    1) base model을 다운로드받는다.
    2) Classifer 부분 만들기
    - flatten 혹은 Global Average Pooling layer 만들기
    - Dense layer(노드 수는 그 전 레이어의 차원 수) 만들기
    - Dense layer(노드 수는 클래스 수) 만들기

    3) 만약 base model은 학습 안 시키면 base_model.trainable = False로 선언하기
    4) Sequential API로(아마 다른 거여도 될 듯) 모델 만들고 그 안에 argument로 넣어주기)
    model = tf.keras.Sequential([ base_model, global_average_layer, dense_layer, prediction_layer ])
    5) model.compile()로 optimizer, loss_function 등 설정
    6) 학습

  • 참고로 이런 경우 6) 학습을 안 한 상태에서 기초적으로 있는 base_model의 학습만 갖고도 model.evaluate()이 가능함.

# 예시 코드
validation_steps=20
loss0, accuracy0 = model.evaluate(validation_batches, steps = validation_steps)

print("initial loss: {:.2f}".format(loss0))
print("initial accuracy: {:.2f}".format(accuracy0))

>>>
20/20 [==============================] - 17s 128ms/step - loss: 0.7049 - accuracy: 0.5370
initial loss: 0.71
initial accuracy: 0.53
  • 몰랐는데 keras.model.fit() 이후에는 History callback(객체임)이 return 된다. 즉, 학습 후에 return 값은 history이다.(아래의 코드 참조)
    : "According to Keras documentation, the model. fit method returns a History callback, which has a history attribute containing the lists of successive losses and other metrics. hist = model.fit(X, y, validation_split=0.2) print(hist.history)"
history = model.fit(train_batches,
                    epochs=EPOCHS,
                    validation_data=validation_batches)
  • plt.ylim([min(plt.ylim()),1]) 같은 거로 ylim의 시작 지점을 약간 dynamically 지정할 수 있나 보다

DeepML

  • Rˆ2의 의미는 무엇일까...
    • R(상관계수)의 제곱이지만 일단 큰 맥락으로는 성능 평가를 위한 지표이고, 1에 가까우면 성능이 좋은 것이다.
    • (y - y_pred)값이 가능해야 하므로 연속적 수치를 갖는 Regression 문제의 평가지표가 된다.
  • Ridge Regression
    • 목적 : 규제(features가 너무 복잡하면 overfitting 되는데, coefficient를 줄여서 그것을 방지함.)
    • 요약 : 고루고루 다 보는데
    • 원리 : To be studied....
    • when to use? : To be studied....
  • Lasso Regression
    • 목적 : Ridge 와 같음
    • 요약 : 큰 도움이 되는 데이터만 집중하여 살림
    • 원리 : To be studied....
    • when to use? : To be studied....
  • Regulirization 전에 Normalization or Standardization을 하게 됨
    : 왜냐하면, 데이터 스케일이 달라서 생긴 coefficient끼리 또 갭 차이가 클 텐데, 그러면 제일 큰 게 많이 영향을 끼치니까 그것을 집중적으로(unfairly) 수식에서 규제하게 될 것이다.

질문

  • 이미지 픽셀 값이 scaled 되어 -1 ~ 1, 혹은 0 ~ 1의 값을 가져도 이미지를 출력해보면 그대로인 것 같다. 혹시 픽셀들의 비율이 중요한 건가...?

  • base_model로 가져온 VGG16 모델에 image_batch(shape은 32, 160, 160, 3)을 넣는다는 건 무슨 의미일까...?
    : 결과적으로 뭔가 달라진 batch가 탄생하긴 했다.

  • flatten layer의 목적이 모든 노드를 다음 노드에 연결해야 해서 1차원벡터로 만들기 위함이라는데 무슨 의미일까...?
    : 여태까지 3차원 tensor로 잘 오다가 왜 끝에만 1차원이 되어야 하는 걸까

  • Linearity / Non-linearity

    • (퍼옴) "선형 시스템이 아무리 깊어지더라도 f(ax+by)=af(x) + bf(y)의 성질 때문에... 즉, linear한 연산을 갖는 layer를 수십개 쌓아도 결국 이는 하나의 linear 연산으로 나타낼 수 있다." 링크
  • PolynomialFeatures 클래스는 train 데이터에 적용하지 않고 test 데이터에 적용해도 된다던데 왜 그럴까?
    : train 데이터에서 평균이나 std 등 뭔가를 구해서 그 값을 test 데이터에 취하는 게 아니어서 사실은 fit() 안해도 된다.

  • 아래의 코드에서 정확하게 validation_batches는 어떤 원리로 학습에 참여하게 되는 걸까..?

EPOCHS = 5

history = model.fit(train_batches,
                    epochs=EPOCHS,
                    validation_data=validation_batches)
profile
'어떻게든 자야겠어'라는 저 아이를 닮고 싶습니다

0개의 댓글