[開発ログ2022.4.18]Microsoft Azure(1)

12165 ワード

1.勉強の内容


1)画像解析例


実習で犬と猫を区別する.
kaggle.com犬および猫の画像データを受信する.
csvファイル、testファイル、trainファイルを受信します.
このとき、今日の作業でGPUを使う必要があるので、Googleドライブのcolabを使っています.
import keras
keras.__version__
ケラスクーに積み込み、
ファイルをロードしてGoogleドライブにアップロードするには、Googleドライブに接続します.
from google.colab import drive
drive.mount('/content/dirve')

ドライブの接続が完了し、必要なライブラリを読み込み中です.
import os, shutil
このとき
suttilは、Shell Script UtilityやLinuxなどのコマンドの作成を許可するツールです.
現在、画像データを分類するために、
フォルダをチェックするコードを使用します.
original_dataset_dir = './drive/MyDrive/datasets/cats_and_dogs/train'

base_dir ='./drive/MyDrive/datasets/cats_and_dogs_small'
デフォルトのデータセットのディレクトリを設定します.
if os.path.exists(base_dir): 
  shutil.rmtree(base_dir) 
os.mkdir(base_dir)
このときbase dirがすでに存在する場合は削除し、存在しない場合はmkdirによってbase dirを生成します.
このbase dirのサブフォルダは後で作成されます.
train_dir = os.path.join(base_dir, 'train')
os.mkdir(train_dir)
validation_dir=os.path.join(base_dir,'validation')
os.mkdir(validation_dir)
test_dir=os.path.join(base_dir,'test')
os.mkdir(test_dir)
これにより、base dirの真下にtrainフォルダ、validationフォルダ、testフォルダが作成されます.
train_cats_dir = os.path.join(train_dir,'cats')
os.mkdir(train_cats_dir)

train_dogs_dir = os.path.join(train_dir,'dogs')
os.mkdir(train_dogs_dir)



validation_cats_dir = os.path.join(validation_dir,'cats')
os.mkdir(validation_cats_dir)

validation_dogs_dir = os.path.join(validation_dir,'dogs')
os.mkdir(validation_dogs_dir)



test_cats_dir = os.path.join(test_dir,'cats')
os.mkdir(test_cats_dir)

test_dogs_dir = os.path.join(test_dir,'dogs')
os.mkdir(test_dogs_dir)
その後、train、validation、testフォルダにdogsディレクトリとcatsディレクトリをそれぞれ作成します.
これによって

サブフォルダが作成されることを確認できます.
画像をコピーしてサブフォルダに入れることができます.
print('Copy files....')
print('---Training file(s) (cat)....')
fnames = ['cat.{}.jpg'.format(i) for i in range(1000)] 
for fname in fnames:
  src = os.path.join(original_dataset_dir, fname)
  dst = os.path.join(train_cats_dir, fname)
  shutil.copy(src,dst)
これにより、猫の画像は0から999まで1000個コピーされます.
このコードをコピーすると、
print('---Validation file(s) (cat)....')
fnames = ['cat.{}.jpg'.format(i) for i in range(1000,1500)]
for fname in fnames:
  src = os.path.join(original_dataset_dir, fname)
  dst = os.path.join(validation_cats_dir, fname)
  shutil.copy(src,dst)

print('---Test file(s) (cat)....')
fnames = ['cat.{}.jpg'.format(i) for i in range(1500,2000)]
for fname in fnames:
  src = os.path.join(original_dataset_dir, fname)
  dst = os.path.join(test_cats_dir, fname)
  shutil.copy(src,dst)
1000~1500個目の画像を検証猫にコピーし、1500~2000個目の画像をテスト猫にコピーしてから入れることがわかります.
cat部分をdogに変えたら
print('---Training file(s) (dog)....')
fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
  src = os.path.join(original_dataset_dir, fname)
  dst = os.path.join(train_dogs_dir, fname)
  shutil.copy(src,dst)

print('---Validation file(s) (dog)....')
fnames = ['dog.{}.jpg'.format(i) for i in range(1000,1500)]
for fname in fnames:
  src = os.path.join(original_dataset_dir, fname)
  dst = os.path.join(validation_dogs_dir, fname)
  shutil.copy(src,dst)

print('---Test file(s) (dog)....')
fnames = ['dog.{}.jpg'.format(i) for i in range(1500,2000)]
for fname in fnames:
  src = os.path.join(original_dataset_dir, fname)
  dst = os.path.join(test_dogs_dir, fname)
  shutil.copy(src,dst) 
入力することで、子犬の画像データもコピーできます.
このとき
srcは、コピーするファイルのフォルダをインポートします.
dstは、コピーするファイルを格納するフォルダです.

このようにprint文を中間に加え,進捗に応じて位置を表示する.
これらのコピーされたファイルを確認するためにコードを作成します.
print('훈련용 고양이 이미지:', len(os.listdir(train_cats_dir)))
print('검증용 고양이 이미지:', len(os.listdir(validation_cats_dir)))
print('테스트용 고양이 이미지:', len(os.listdir(test_cats_dir)))

print('훈련용 강아지 이미지:', len(os.listdir(train_dogs_dir)))
print('검증용 강아지 이미지:', len(os.listdir(validation_dogs_dir)))
print('테스트용 강아지 이미지:', len(os.listdir(test_dogs_dir)))

これに適したニューラルネットワークを構築します.
from keras import layers
from keras import models

model = models.Sequential()
model.add(layers.Conv2D(32,(3,3),activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64,(3,3),activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64,(3,3),activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(128,(3,3),activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Flatten())
model.add(layers.Dense(512,activation='relu'))
model.add(layers.Dense(1,activation='sigmoid'))
ニューラルネットワークの構造が決定されると,ニューラルネットワークがコンパイルされる.
from tensorflow.keras import optimizers

model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])
このニューラルネットワークに画像ファイルを適用するには、画像のスケールを行い、ライブラリを読み込む必要があります.
from keras.preprocessing.image import ImageDataGenerator
# 이미지 스케일을 위한 도구

train_datagen = ImageDataGenerator(rescale=1./255)
validation_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=(150,150),
    batch_size=20,
    class_mode='binary'
)

validation_generator = validation_datagen.flow_from_directory(
    validation_dir,
    target_size=(150,150),
    batch_size=20,
    class_mode='binary'
)
これらのデータをニューラルネットワークに適用します.
model.fit_generator(
    train_generator,
    epochs=30,
    steps_per_epoch=100,
    validation_data = validation_generator,
    validation_steps = 50
)
これは、データが大きな画像ファイルを使用して行われるため、時間がかかります.GPUを使用します.

このように学習したデータをファイルに保存します.
model.save('cats_and_dogs_small_1.h5')
この場合、保存しない場合は、モデルを新規作成するたびに時間のかかる操作を再実行する必要があります.
これらのデータを視覚的に確認するためにグラフを描いた.
history = model.history

import matplotlib.pyplot as plt

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(len(acc))

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()

これにより、最適な実施回数を決定することができる.
トレーニング用画像データを追加します.
datagen = ImageDataGenerator(
      rotation_range=40,#각도를 40도를 돌린다
      width_shift_range=0.2,
      height_shift_range=0.2,
      shear_range=0.2,
      zoom_range=0.2,
      horizontal_flip=True,#수평으로 좌우를 바꿔서 증식한다
      fill_mode='nearest')#이동했을때 빈공간을 뭘로 채울것인가. nearest: 근처의색으로 채워준다.

# 이미지 전처리 유틸리티 모듈
from keras.preprocessing import image

fnames = sorted([os.path.join(train_cats_dir, fname) for fname in os.listdir(train_cats_dir)])

# 증식할 이미지 선택합니다
img_path = fnames[3]

# 이미지를 읽고 크기를 변경합니다
img = image.load_img(img_path, target_size=(150, 150))

# (150, 150, 3) 크기의 넘파이 배열로 변환합니다
x = image.img_to_array(img)

# (1, 150, 150, 3) 크기로 변환합니다
x = x.reshape((1,) + x.shape)

# flow() 메서드는 랜덤하게 변환된 이미지의 배치를 생성합니다.
# 무한 반복되기 때문에 어느 지점에서 중지해야 합니다!
i = 0
for batch in datagen.flow(x, batch_size=1):
    plt.figure(i)
    imgplot = plt.imshow(image.array_to_img(batch[0]))
    i += 1
    if i % 4 == 0:
        break

これにより、3番(4番目)の画像を少しずつ移動する画像に増殖させる.

この場合,学習データは増殖できるが,検証やテストに用いるデータは増殖できないことに注意する.
新しいニューラルネットワークを作る.
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu',
input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))



model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=1e-4),
metrics=['acc'])
このようにニューラルネットワークを再構築します.
これに基づいて画像を適用します.
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,)



# 검증 데이터는 증식되어서는 안 됩니다!
test_datagen = ImageDataGenerator(rescale=1./255)



train_generator = train_datagen.flow_from_directory(
# 타깃 디렉터리
train_dir,
# 모든 이미지를 150 × 150 크기로 바꿉니다
target_size=(150, 150),
batch_size=20,
# binary_crossentropy 손실을 사용하기 때문에 이진 레이블을 만들어야 합니다
class_mode='binary')



validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')



history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=100,
validation_data=validation_generator,
validation_steps=50)

これで100話が終わると保存されます
model.save('cats_and_dogs_small_2.h5')
これもグラフで可視化確認します.
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']



epochs = range(len(acc))



plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()



plt.figure()



plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()

以前のグラフよりも回数が多く、より緻密になっていることがわかります.

2.学習内容の難点


Web上で大量のデータを使用しているため、アップロードが遅い、コードの実行が正しくないなどのエラーが発生しています.

3.解決方法


これらのエラーはすでに経験している人がいますが、インターネット上の検索を通じて、グーグルドライブアプリケーションを使用するより迅速なアップロード方法を見つけることができます.
実行できないエラーはcolabが提供するリソースを減らすことで解決でき、batch sizeを減らすことができます.

4.勉強の心得


これまで、パソコンを使ったコーディングはそれほど難しくなかったが、大量のデータを持つコードについては、授業中の同級生や先生たちを含め、パソコンの性能が異なり、速度も異なり、設備の重要性にも気づいた.
これに関連して、クラウドサービスを利用するために、Azureについて簡単に紹介しただけで、これらのサービスを利用することでコンピュータの性能の不足を緩和できることを望んでいるので、次の授業を期待しています.