シリーズ記事の目次
目次
序文
このプロジェクトは、畳み込みニューラル ネットワーク (CNN) モデルに基づいて、収集された猫の画像データをトレーニングします。データ拡張テクノロジーを使用し、残差ネットワークを組み合わせることで、モデルのパフォーマンスを向上させ、さまざまな猫の種類を正確に識別することを目指しています。
まず、このプロジェクトでは、画像認識タスク用に特別に設計された深層学習モデルである CNN モデルを利用します。このモデルは、複数の畳み込み層とプーリング層を通じて、画像内の特徴を効果的にキャプチャし、猫のカテゴリ認識のための強力な学習機能を提供できます。
次に、収集したデータを学習させることで、猫の種類を正確に識別できるモデルを構築することを目的としています。モデルをさまざまな種やシナリオに一般化できるように、さまざまな猫の画像が含まれています。
モデルのパフォーマンスをさらに向上させるために、データ拡張技術が採用されました。データ拡張では、トレーニング セット内の画像に対する回転、反転、拡大縮小などの操作によって、より多くのバリアントが生成されます。これにより、モデルがさまざまな視野角や条件に適応しやすくなります。
同時に、残差ネットワークの考え方を導入すると、ディープネットワークトレーニングにおける勾配消失の問題を解決し、モデルのトレーニング効果を向上させることができます。この組み合わせアプローチにより、モデルがより堅牢かつ正確になります。
このプロジェクトを通じて、ついに猫の種類を正確に識別するという目標が達成されました。これはペット分野や動物研究などでの実用化の可能性があり、関連分野に効率的で信頼性の高いツールを提供します。
全体的なデザイン
このパートには、システム全体の構成図とシステム フローチャートが含まれます。
全体システム構成図
システムの全体構成を図に示します。
システムフローチャート
システムフローを図に示します。
動作環境
この部分には、コンピューティング クラウド サーバー、Python 環境、TensorFlow 環境、MySQL 環境が含まれます。
详见博客。
モジュールの実装
このプロジェクトには、データ前処理、データ拡張、通常の CNN モデル、残差ネットワーク モデル、モデル生成の 5 つのモジュールが含まれています。各モジュールの機能紹介と関連コードを以下に示します。
1. データの前処理
ブラウザを開いて、ラグドール、ボンベイ、シャム、ブリティッシュ ショートヘアの猫の写真を検索します。バッチ ダウンローダーを使用して画像をダウンロードし、明らかな特徴を持つ画像をデータ セットとして選択します。使用された写真には、ラグドール猫 101 匹、ボンベイ猫 97 匹、オウム猫 101 匹、ブリティッシュショートヘア猫 85 匹の合計 384 枚の写真が含まれています。 (このうち、プロジェクト コード内の /cat_kind_model/cat_data_100
と /cat_kind_model/cat_data_224
もダウンロードできます)
画像名の変更、形式とサイズの調整、画像のトレーニング セットとテスト セットへの均等な分割など、データ セットを前処理します。
import os #导入各种模块
from PIL import Image
import argparse
from tqdm import tqdm
class PrepareData: #准备数据类
def __init__(self, options): #初始化
self.moudle_name = "prepare data"
self.options = options
self.src_images_dir = self.options.src_images_dir
self.save_img_with = self.options.out_img_size[0]
self.save_img_height = self.options.out_img_size[1]
self.save_dir = self.options.save_dir
#统一图片类型
def renameJPG(self, filePath, kind): #图片重命名
#filePath:图片文件的路径,kind: 图片的种类标签
images = os.listdir(filePath)
for name in images:
if (name.split('_')[0] in ['0', '1', '2', '3']):
continue
else:
os.rename(filePath + name, filePath + kind + '_' + str(name).split('.')[0] + '.jpg')
#调用图片处理
def handle_rename_covert(self): #重命名处理
save_dir = self.save_dir
#调用统一图片类型
list_name = list(os.listdir(self.src_images_dir))
print(list_name)
train_dir = os.path.join(save_dir, "train")
test_dir = os.path.join(save_dir, "test")
#1.如果已经有存储文件夹,执行则退出
if not os.path.exists(save_dir):
os.mkdir(save_dir)
os.mkdir(train_dir)
os.mkdir(test_dir)
list_source = [x for x in os.listdir(self.src_images_dir)]
#2.获取所有图片总数
count_imgs = 0
for i in range(len(list_name)):
count_imgs += len(os.listdir(os.path.join(self.src_images_dir, list_name[i])))
#3.开始遍历文件夹,并处理每张图片
for i in range(len(list_name)):
count = 1
count_of_each_kind = len(os.listdir(os.path.join(self.src_images_dir, list_name[i])))
handle_name = os.path.join(self.src_images_dir, list_name[i] + '/')
self.renameJPG(handle_name, str(i))
#调用统一图片格式
img_src_dir = os.path.join(self.src_images_dir, list_source[i])
for jpgfile in tqdm(os.listdir(handle_name)):
img = Image.open(os.path.join(img_src_dir, jpgfile))
try:
new_img = img.resize((self.save_img_with, self.save_img_height), Image.BILINEAR)
if (count > int(count_of_each_kind * self.options.split_rate)):
new_img.save(os.path.join(test_dir, os.path.basename(jpgfile)))
else:
new_img.save(os.path.join(train_dir, os.path.basename(jpgfile)))
count += 1
except Exception as e:
print(e)
#参数设置
def main_args():
parser = argparse.ArgumentParser()
parser.add_argument('--src_images_dir', type=str, default='../dataOrig/',help="训练集和测试集的源图片路径")
parser.add_argument("--split_rate", type=int, default=0.9, help='将训练集二和测试集划分的比例,0.9表示训练集占90%')
parser.add_argument('--out_img_size', type=tuple, default=(100, 100),help='保存图片的大小,如果使用简单网络结构参数大小为(100,100),如果使用resnet大小参数为(224,224)')
parser.add_argument("--save_dir", type=str, default='../cat_data_100', help='训练数据的保存位置')
options = parser.parse_args()
return options
if __name__ == "__main__":
#获取参数对象
options = main_args()
#获取类对象
pd_obj = PrepareData(options)
pd_obj.handle_rename_covert()
2. データの強化
いわゆるデータ拡張とは、反転、回転、拡大縮小、ランダムなトリミング、シフト、ノイズの追加などの操作を通じて既存のデータ セットを拡張することです。このプロジェクトのデータ量は少ないため、画像の深い特徴を抽出することは不可能であり、深い残差ネットワークを使用すると、モデルが過剰適合しやすくなります。
from keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img
import argparse, os
from PIL import Image
from tqdm import tqdm #进度条模块
datagen = ImageDataGenerator(
rotation_range=40, #整数,数据提升时图片随机转动的角度
width_shift_range=0.2,#浮点数,图片宽度的某个比例,数据提升时图片水平偏移的幅度
height_shift_range=0.2,#浮点数,图片高度的某个比例,数据提升时图片竖直偏移的幅度
rescale=1. / 255, #重放缩因子,默认为None
shear_range=0.2, #浮点数,剪切强度(逆时针方向的剪切变换角度)
zoom_range=0.2, #浮点数或形如[lower,upper]的列表,随机缩放的幅度
#若为浮点数,则相当于[lower,upper] = [1 - zoom_range, 1+zoom_range]
horizontal_flip=True, #布尔值,进行随机水平翻转
vertical_flip=False, #布尔值,进行随机竖直翻转
fill_mode='nearest', #‘constant’,‘nearest’,‘reflect’或‘wrap’之一,
#进行变换时超出边界的点将根据本参数给定的方法进行处理
cval=0, #浮点数或整数,当fill_mode=constant时,指定要向超出边界的点填充值
channel_shift_range=0, #随机通道转换的范围
)
def data_aug(img_path, save_to_dir, agu_num):
img = load_img(img_path)
#获取被扩充图片的文件名部分,作为扩充结果图片的前缀
save_prefix = os.path.basename(img_path).split('.')[0]
x = img_to_array(img)
x = x.reshape((1,) + x.shape)
i = 0
for batch in datagen.flow(x, batch_size=1, save_to_dir=save_to_dir,
save_prefix=save_prefix, save_format='jpg'):
i += 1
#保存agu_num张数据增强图片
if i >= agu_num:
break
#读取文件夹下的图片,并进行数据增强,将结果保存到dataAug文件夹下
def handle_muti_aug(options):
src_images_dir = options.src_images_dir
save_dir = options.save_dir
list_name = list(os.listdir(src_images_dir))
for name in list_name:
if not os.path.exists(os.path.join(save_dir, name)):
os.mkdir(os.path.join(save_dir, name))
for i in range(len(list_name)):
handle_name = os.path.join(src_images_dir, list_name[i] + '/')
#tqdm()为数据增强添加进度条
for jpgfile in tqdm(os.listdir(handle_name)):
#将被扩充的图片保存到增强的文件夹下
Image.open(handle_name+jpgfile).save(save_dir+'/'+list_name[i]+'/'+jpgfile)
#调用数据增强过程函数
data_aug(handle_name+jpgfile, os.path.join(options.save_dir, list_name[i]), options.agu_num)
def main_args():
parser = argparse.ArgumentParser()
parser.add_argument('--src_images_dir', type=str, default='../source_images/', help="需要被增强训练集的源图片路径")
parser.add_argument("--agu_num", type=int, default=19, help='每张训练图片需要被增强的数量,这里设置为19,加上本身的1张,每张图片共计变成20张')
parser.add_argument("--save_dir", type=str, default='../dataAug', help='增强数据的保存位置')
options = parser.parse_args()
return options
if __name__ == "__main__":
options = main_args()
handle_muti_aug(options)
データ増強の進行状況を図に示します。
図に示すように、データ セットは元のサイズの 20 倍に拡張されます。
その他の関連ブログ
プロジェクトのソースコードのダウンロード
詳細については、私のブログ リソースのダウンロード ページをご覧ください。
その他の情報をダウンロードする
人工知能に関連する学習ルートと知識システムをさらに理解したい場合は、私の他のブログ「 Heavy | Complete Artificial Intelligence AI Learning - Basics」を参照してください。知識学習ルート、すべての資料はルーチンに従わずにネットワーク ディスクから直接ダウンロードできます》
このブログでは、Github の有名なオープン ソース プラットフォームである AI について言及しています技術プラットフォームと関連分野の専門家 : Datawhale、ApacheCN、AI Youdao と Huang Haiguang 博士は約 100G の関連情報を持っており、友人全員のお役に立てれば幸いです。