[Aidemy] 이동 학습을 사용하여 차의 차체 유형을 식별한다

8048 단어 Python
개시하다
Aidemy Premium 프로그램에서 3개월간 데이터 분석 과정을 수강했습니다.
본 보도는 그 최종 과제이다.
이번에 vggg16을 이용하여 이동 학습을 하여 최종적으로 차의 차체 유형을 식별하였다.
차체 유형: 소형 화물차, 소형차, 승용차, SUV
상술한 분류의 이유는 뒤에 서술할 것이다.
운영 환경
Google Colab에서 구현되었습니다.
신체 유형 식별을 초래한 경과
당초 10개 차종의 식별을 진행할 예정이었다.그러나 데이터를 수집해 학습한 결과 정확도는 20% 정도에 불과했다.
이상하게 아이디미의 강사에게 문의했더니 인식의 종류가 많을수록 데이터 수도 필요하다는 것을 알게 돼 현재 구축된 모델은 한계가 있어 데이터 수를 늘리거나 식별 종류를 줄이는 대응 전략을 제시했다.
이에 따라 인식의 종류를 줄이기 위해 신체 유형의 식별이 결정됐다.
게다가 상술한 방침 전환의 관계로 원래 수집한 이미지를 이용하여 신체 유형을 식별하고 있다.
※ 따라서 이미지 수집 검색어에는 구체적인 차명이 표시됩니다.
카탈로그
  • 이미지 수집
  • 이미지의 허위 보고
  • 이미지의 읽기 데이터 분할
  • 전이 학습(vgg16)
  • 모델의 평가
  • 마지막
  • 1. 이미지 수집
    그림 수집은 icrawler라는 파이톤이라는 프로그램 라이브러리를 사용해서 커튼을 쳤다.
    세 줄 정도만 쓰면 그림을 쉽게 수집할 수 있다.
    스컬링의 브라우저는 Google도 그렇게 할 수 있다고 지정하지만, 이런 기사를 잘 다루지 않아서 빙에서 실행되었습니다.
    이미지 수집
    # スクレイピング用のライブラリをインストール
    !pip install icrawler
    import os
    # Bingでスクレイピングを行うためのモジュール
    from icrawler.builtin import BingImageCrawler
    # 検索名をリストに
    SearchName=["ヤリス","カローラ","アルファード","日産ノート","トヨタライズ","ハリアー","トヨタアクア","ヴォクシー","フリード","スカイライン","ヴェゼル","プリウス"]
    # 画像の取得枚数上限
    Imgnum=200
    # スクレイピング用のフォルダ作成
    os.makedirs("./Original",exist_ok=True)
    # スクレイピング開始
    for name in SearchName:
      crawler=BingImageCrawler(storage={"root_dir":"./Original/"+name})
      crawler.crawl(keyword=name, max_num=200)
    
    200장 정도의 롤업을 할 수 있을 줄 알았는데 빙을 이용해서도 완벽하게 롤업을 할 수 없었고 폴더별로 100장 정도밖에 안 됐어요.
    집합이 없습니다.
    그런 다음 이미지를 보완합니다.
    2. 이미지의 허위 보고
    이미지의 페이퍼는 Kersa의 ImageDataGeneratr를 사용하여 1장→10장의 이미지를 추가했습니다.
    다음 코드를 통해 회전, 너비 높이의 이동, 반전 등을 진행한다.
    이미지 수집
    import os
    import glob
    from keras.preprocessing.image import load_img, img_to_array
    from keras.preprocessing.image import ImageDataGenerator
    import matplotlib.pyplot as plt
    import numpy as np
    #画像の水増し
    # 1枚当たりから水増しする枚数
    N_img=10
    # 元画像の置いてあるフォルダを指定
    Original_path="/content/drive/MyDrive/Original"
    dirlist=os.listdir(Original_path)
    # .ipynb_checkpointsというファイルを取得しないように各車種の名前がついたフォルダを指定する
    dirlist=[filename for filename in dirlist if not filename.startswith(".")]
    # 水増しの処理 水増し画像の出力先フォルダは元画像と同じにした
    for name in dirlist:
      input_path=Original_path+'/'+name
      files=glob.glob(input_path+'/*.jpg')
      output_path=Original_path+'/'+name
      for i,file in enumerate(files):
        img=load_img(file)
        x=img_to_array(img)
        x = np.expand_dims(x, axis=0)
        # ImageDataGeneratorの生成
        datagen = ImageDataGenerator(
        rotation_range=30, # ランダムに回転させる範囲
        width_shift_range=0.3, # ランダムに幅をシフトさせる範囲
        height_shift_range=0.3, # ランダムに高さをシフトさせる範囲
        zoom_range=0.3,        # ランダムにズームさせる範囲
        horizontal_flip=True, # ランダムに水平方向に反転させる
        vertical_flip=True, # ランダムに垂直方向に反転させる
        )
        # N_img枚数分画像を水増し
        dg= datagen.flow(x, batch_size=1, save_to_dir=output_path, save_prefix='img', save_format='jpg')
        for i in range(N_img):
            batch = dg.next()
    
    가수가 끝난 후/content/drive/MyDrive/Original 바로 아래에서 승용차, 소형차, SUV, 소형화물차 폴더를 제작하여 다음과 같은 방식으로 차종을 분류하여 폴더(수공)에 배치한다.
    승용차: 천간선, 화관
    소형 화물차: VOXY, 알파, 프레드
    소형차: 사용권, AQUA, 노트북
    SUV: 할리아 슬레이스, 베르사유
    3. 이미지 읽기 데이터의 분할
    이어서 수집되고 허위로 보고된 이미지 데이터를 읽는다.읽기 부분 처리 등은 아이디미의'남녀인식'강의를 참고했다.
    이미지 수가 많아서인지 읽을 때 for를 많이 사용했기 때문인지는 알 수 없지만 GPU 사용에 20분이 걸리는 경우도 있다.
    나는 데이터를 대량으로 사용하는 상황에서 속도를 주의해서 코드를 쓸 필요가 있다고 생각한다.
    그림 읽기와 데이터 분할은 다음 코드로 진행됩니다.
    이미지 읽기 데이터 분할
    from collections import  defaultdict
    import matplotlib.pyplot as plt
    import numpy as np
    from tensorflow.keras.utils import to_categorical
    import cv2
    import os
    import random
    from google.colab.patches import cv2_imshow
    import glob
    dirlist=os.listdir("/content/drive/MyDrive/Original")
    dirlist=[filename for filename in dirlist if not filename.startswith(".")]
    print(dirlist)
    car_path_dict=defaultdict(list)
    car_img_dict=defaultdict(list)
    # ボディタイプがkey,valueが画像のパスを格納したリストである辞書を作成
    for key in dirlist:
      car_path_dict[key]=glob.glob("/content/drive/MyDrive/Original/"+key+"/*/*")
    
    for key,values in car_path_dict.items():
      print(key,len(values))
    # パスを格納した辞書から画像を読み込んだ辞書を作成する
    # 時間がかかります
    for key,values in car_path_dict.items():
      print(key)
      for value in values:
        img=cv2.imread(value)
        img=cv2.resize(img,(50,50))
        car_img_dict[key].append(img)
    
    Xtmp=[]
    ytmp=[]
    for values in car_img_dict.values():
      for value in values:
        Xtmp.append(value)
    for k,v in enumerate(car_img_dict):
      print(k,v)
      ytmp=ytmp+[k]*len(car_img_dict[v])
    X=np.array(Xtmp)
    y=np.array(ytmp)
    
    # 画像の順番をシャッフルする
    index=np.random.permutation(np.arange(len(X)))
    X=X[index]
    y=y[index]
    
    # 画像を分割する 訓練8割、テスト2割
    X_train = X[:int(len(X)*0.8)]
    y_train = y[:int(len(y)*0.8)]
    X_test = X[int(len(X)*0.8):]
    y_test = y[int(len(y)*0.8):]
    
    # ラベルづけを行う
    y_train=to_categorical(y_train)
    y_test=to_categorical(y_test)
    
    4. 이동 학습(vgg16)
    드디어 공부를 해야겠다.이번에는 vggg16에 따라 전이 학습을 진행했다.
    과도 학습
    from tensorflow.keras.layers import Activation,BatchNormalization, Conv2D, MaxPooling2D
    from tensorflow.keras.layers import Dense, Dropout, Flatten, Input
    from tensorflow.keras.applications.vgg16 import VGG16
    from tensorflow.keras.models import Model, Sequential
    from tensorflow.keras import optimizers
    
    input_tensor=Input(shape=(50,50,3))
    vgg16=VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)
    
    top_model = Sequential()
    top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
    top_model.add(BatchNormalization())
    top_model.add(Dense(512, activation='relu'))
    top_model.add(Dropout(0.2))
    top_model.add(Dense(256, activation='relu'))
    top_model.add(Dense(64, activation='relu'))
    top_model.add(Dropout(0.2))
    top_model.add(Dense(5, activation='softmax'))
    model=Model(inputs=vgg16.input,outputs=top_model(vgg16.output))
    
    for layer in model.layers[:15]:
      layer.trainable = False
    model.compile(loss='categorical_crossentropy',
                  optimizer=optimizers.Adam(lr=1e-4, beta_1=0.9,beta_2=0.999,decay=0.0),
                  metrics=['accuracy'])
    
    history = model.fit(X_train, y_train, batch_size=64, epochs=50, verbose=1, validation_data=(X_test, y_test))
    scores = model.evaluate(X_test, y_test)
    print("Test loss",scores[0])
    print("Test accuracy",scores[1])
    #acc, val_accのプロット
    plt.plot(history.history["accuracy"], label="accuracy", ls="-", marker="o")
    plt.plot(history.history["val_accuracy"], label="val_accuracy", ls="-", marker="x")
    plt.ylabel("accuracy")
    plt.xlabel("epoch")
    plt.legend(loc="best")
    plt.show()
    
    5. 모델 평가
    훈련 데이터는 순조롭게 학습할 수 있지만 테스트 데이터의 정확도는 낮아 과도한 학습임을 알 수 있다.
    Droput을 가져오더라도 과도한 학습을 일으킬 수 있다.
    또 테스트 데이터는 곧 한계에 도달할 것으로 보인다.

    6. 고찰
    나는 상술한 결과를 초래한 이유를 고찰하고 싶다.
    • 이미지 크기 50×작게 50까지
    • 자동차 자체뿐만 아니라 배경이 있는 이미지도 있어 배경을 방해할 수 있다.
    ・원본 모델의 구축이 이번 사건과 맞지 않을 수 있음
    /데이터 수가 적습니까?→차종별 약 3000장(하지만 많이 늘었다)
    ・테스트 데이터 수량이 적다?
    · 처음부터 신체 유형을 식별하려는 것은 아니므로 분류에 적합한 이미지를 수집하지 않았을 수 있습니다.
    →'세단','소형차','소형 화물차','SUV'를 검색해 이미지를 수집하면 이번 주제에 더 적합한 이미지를 수집할 수 있다.
    정밀도를 표시하지 않았기 때문에 학습에 사용할 이미지 데이터의 크기를 100으로 설정합니다×100번의 재학습 결과는 다음과 같다.
    (epoch수 끊기, 30)
    다소 편차가 있지만 이미지 크기가 작은 모델에 비해 정밀도를 높일 수 있다.
    간혹 가격이 갑자기 떨어지는 물건이 있는 것은 배경의 영향으로 물의 영향을 더해 소음 같은 이미지로 들어가기 때문이다.
    정확도가 높아졌지만 학습 원가가 상승하고 시간이 길어져서 균형을 고려할 필요가 있다고 생각합니다.

    7. 소감
    과제 제출이 임박해 애플리케이션으로 활용하지 못해 아쉽다.나는 충분한 시간이 필요하다는 것을 다시 배웠다.
    또 좋은 데이터만이 좋은 분석 결과를 얻을 수 있다는 것을 몸소 체험했다.
    기계 학습에 관심이 많지만 코드를 어떻게 쓰는지, 구조가 어떤지 사실 잘 몰라서 어느 정도 정밀도 있는 학습 모델을 구축할 수 있어서 기쁩니다.
    저는 자연 언어 처리와 기타 데이터 분석 방법 등에 관심이 많아서 앞으로도 계속 공부할 것입니다.

    좋은 웹페이지 즐겨찾기