[授業6週目20日目]機械学習-11
1.学習内容
今日は画像を読むことで奥行き学習モデルを作ってみました.
まずGoogleドライブに画像資料を入れて、まず画像を読みます.import keras
keras.__version__
from google.colab import drive
drive.mount('/content/drive')
import os, shutil #리눅스 명령어 같은거 쓸수 있는 스크립트(shutil)
# 원본 데이터 셋을 압축 해제한 디렉터리 경로
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): #해당되는 경로가'base_dir'있는지 확인하는 매서드
shutil.rmtree(base_dir) #있으면 기존의 것을 삭제하고(rmtree)
os.mkdir(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)
そして、「猫」と「犬」の写真を分けて、上のフォルダにそれぞれ置いて、コピーコードを書きます.# 훈련용 고양이 사진 디렉터리
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)
# 처음 1000개의 고양이 이미지를 train_cats_dir에 복사합니다.
print('Copy files....')
print('---traing 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.copyfile(src, dst)
# 다음 500개 고양이 이미지를 validaion_cats_dir에 복사합니다.
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.copyfile(src, dst)
# 다음 500개 고양이 이미지를 test_cats_dir에 복사합니다.
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.copyfile(src, dst)
# 처음 1000개의 강아지 이미지를 train_dogs_dir에 복사합니다.
print('---traing 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.copyfile(src, dst)
# 다음 500개 강아지 이미지를 validaion_dogs_dir에 복사합니다.
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.copyfile(src, dst)
# 다음 500개 강아지 이미지를 test_dogs_dir에 복사합니다.
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.copyfile(src, dst)
上のコードは、フォルダが重複しないようにセルに書かなければなりません.
これを学習し、検証するアクティビティは「validation」であり、「train」とともに使用し、ここに戻ったモデルの残りの「test」で、正確性がどれほど高いかを確認します.
上のコピーができたら、下の印刷コードで数量を確認してください.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)))
ファイルがうまくコピーされていることを確認したので、モデルを作成します.先週の金曜日に学んだ内容によると、
画像中のニューロンが多ければ多いほどモデルの可読性がよくなるため,11層を作成してモデルを作成することができる.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(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.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid')) #이진분류는 'sigmoid'
ちなみに、第1のConv 2 D層の第1のパラメータ32はフィルタ値である.
合成乗算に用いるフィルタは、画像から特徴を分離する機能を有する.
フィルタの値は、合成乗算に用いるフィルタの種類(個数)であり、出力空間の階層(深さ)を決定する.
2番目のパラメータ(3,3)はkernel size値です.
kernel sizeは、乗数を合成するためのフィルタ(=カーネル)のサイズです.
参考資料:https://codetorial.net/tensorflow/convolutional_neural_network.html
最後の層が0,1で、そのうちの1つが出ればいいので、バイナリ分類「dense」の「sigmoid」
に参加
階層が深ければ深いほど,奥深い問題を解くことができる.
これを要約して皆さんに見せると『Compile』がダメなので間違い
(Pythonの内蔵関数として、文字列をコンパイルし、Pythonコードを返します.)from tensorflow.keras import optimizers
model. compile(loss='binary_crossentropy', #둘중 하나의 값이 결과값이 나와야 해서.
optimizer=optimizers.RMSprop(lr=1e-4), # 학습률설정. 0.0001 정도 됨.
metrics=['acc']) #'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'
)
作成したモデルを変換しながらフィットするようになりました.
何度も繰り返してこそ結果が出るので、epochを30回します.model.fit_generator(
train_generator,
epochs=30,
steps_per_epoch=100,
validation_data=validation_generator,
validation_steps=50
)
このようにしたモデルは単独で保存できます.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()
訓練用は回転すればするほど100%近い精度で,検証用はある時点で停止する.
検証された画像がいくつかない場合は、画像を増殖する必要があります.例えば、猫の写真が1枚あれば、ランダムに1枚の画像を左右に反転させてからレンズを回して、このようにして複数枚作ることができます.
この方式を用いる手法は以下の通りである.datagen = ImageDataGenerator(
rotation_range=40, #돌리는 각도
width_shift_range=0.2, #수평으로 돌리는 각도(20%), 좌우
height_shift_range=0.2, #상하로 돌림
shear_range=0.2,
zoom_range=0.2, #확대 축소
horizontal_flip=True, #수평으로 좌우로 바꿈
fill_mode='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
今回は別の条件でモデルを作ってみました.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=32, #검증에는 증식사용하지 않음(test에서만)
class_mode='binary')
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=100,
validation_data=validation_generator,
validation_steps=50)
最初はまだ勉強が終わっていないので、「train generator」のbatch sizeを32から20に下げました.
そしてグラフで比較した結果、以下のようになりました.
イメージを増やして学習の精度を高めたようだ.(矢印によって示されるアップグレードされた図面を表示)
2.難点と解決策
困ったことがあると言えば、途中で写し取るのは難しく、何の命令なのか分かりません.
理解できないまま过去のことをビデオで见直して理解した.
そこで命令文はグーグル検索を行い、コメントを再開した.
3.勉強の心得
モデルを保存したいときに使えるようになり、結果値が見えて嬉しいです.
明日も勉强するそうで、ちょっと楽しみです.
Reference
この問題について([授業6週目20日目]機械学習-11), 我々は、より多くの情報をここで見つけました
https://velog.io/@sam334/수업-6째주-20일차-머신러닝-11
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import keras
keras.__version__
from google.colab import drive
drive.mount('/content/drive')
import os, shutil #리눅스 명령어 같은거 쓸수 있는 스크립트(shutil)
# 원본 데이터 셋을 압축 해제한 디렉터리 경로
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): #해당되는 경로가'base_dir'있는지 확인하는 매서드
shutil.rmtree(base_dir) #있으면 기존의 것을 삭제하고(rmtree)
os.mkdir(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)
# 훈련용 고양이 사진 디렉터리
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)
# 처음 1000개의 고양이 이미지를 train_cats_dir에 복사합니다.
print('Copy files....')
print('---traing 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.copyfile(src, dst)
# 다음 500개 고양이 이미지를 validaion_cats_dir에 복사합니다.
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.copyfile(src, dst)
# 다음 500개 고양이 이미지를 test_cats_dir에 복사합니다.
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.copyfile(src, dst)
# 처음 1000개의 강아지 이미지를 train_dogs_dir에 복사합니다.
print('---traing 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.copyfile(src, dst)
# 다음 500개 강아지 이미지를 validaion_dogs_dir에 복사합니다.
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.copyfile(src, dst)
# 다음 500개 강아지 이미지를 test_dogs_dir에 복사합니다.
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.copyfile(src, dst)
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(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.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid')) #이진분류는 'sigmoid'
from tensorflow.keras import optimizers
model. compile(loss='binary_crossentropy', #둘중 하나의 값이 결과값이 나와야 해서.
optimizer=optimizers.RMSprop(lr=1e-4), # 학습률설정. 0.0001 정도 됨.
metrics=['acc']) #'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
)
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, #돌리는 각도
width_shift_range=0.2, #수평으로 돌리는 각도(20%), 좌우
height_shift_range=0.2, #상하로 돌림
shear_range=0.2,
zoom_range=0.2, #확대 축소
horizontal_flip=True, #수평으로 좌우로 바꿈
fill_mode='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
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=32, #검증에는 증식사용하지 않음(test에서만)
class_mode='binary')
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=100,
validation_data=validation_generator,
validation_steps=50)
困ったことがあると言えば、途中で写し取るのは難しく、何の命令なのか分かりません.
理解できないまま过去のことをビデオで见直して理解した.
そこで命令文はグーグル検索を行い、コメントを再開した.
3.勉強の心得
モデルを保存したいときに使えるようになり、結果値が見えて嬉しいです.
明日も勉强するそうで、ちょっと楽しみです.
Reference
この問題について([授業6週目20日目]機械学習-11), 我々は、より多くの情報をここで見つけました
https://velog.io/@sam334/수업-6째주-20일차-머신러닝-11
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
Reference
この問題について([授業6週目20日目]機械学習-11), 我々は、より多くの情報をここで見つけました https://velog.io/@sam334/수업-6째주-20일차-머신러닝-11テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol