初入人工智能
学习人工智能一个星期,入门是通过mooc来入门的,这一个星期过的也算是很痛苦,学到了很多。对于人工智能,虽然说python是基础,但是真的接手的时候,还是感觉python跟没学过的一样。写这篇博客的原由,是对这几天的总结,以下是我个人观点,而且也没什么技术含量,代码来源于mooc。
识图入门程序——猫狗识别
- 对于文件的操作,这一块主要数据放面的,不是很重要
源代码是基于linux系统,我这里就直接下载,通过zipfile36 和 os库进行操作。
import os
import zipfile36
import random
import tensorflow as tf
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from shutil import copyfile
"""
!wget --no-check-certificate \
"https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_3367a.zip" \
-O "/tmp/cats-and-dogs.zip"
"""
local_zip = 'F:/tmp/cats-and-dogs.zip'
zip_ref = zipfile36.ZipFile(local_zip, 'r')
zip_ref.extractall('F:/tmp')
zip_ref.close()
print(len(os.listdir('F:/tmp/PetImages/Cat/')))
print(len(os.listdir('F:/tmp/PetImages/Dog/')))
接下来就是对训练集和测试集的区分(训练集:用于机器学习的数据,测试集就是验证结果)
#建立猫和狗的训练和测试文件
try:
#YOUR CODE GOES HERE
os.mkdir('F:/tmp/cats-and-dogs')
os.mkdir('F:/tmp/cats-and-dogs/test')
os.mkdir("F:/tmp/cats-and-dogs/train")
os.mkdir('F:/tmp/cats-and-dogs/train/dogs')
os.mkdir('F:/tmp/cats-and-dogs/train/cats')
os.mkdir('F:/tmp/cats-and-dogs/test/dogs')
os.mkdir('F:/tmp/cats-and-dogs/test/cats')
except OSError:
pass
#数据分离
import shutil
def split_data(SOURCE, TRAINING, TESTING, SPLIT_SIZE):
# YOUR CODE STARTS HERE
files=[]
for filename in os.listdir(SOURCE):
file = SOURCE+filename
if os.path.getsize(file) > 0:
files.append(filename)
else:
print(filename + "文件是空文件!")
train_len = int(len(files)) * SPLIT_SIZE#按照90%的图片用于训练
train_len = int(train_len)
print("训练长度是:{}".format(train_len))
test_len = int(len(files) - train_len)
shuffled_set = random.sample(files, len(files))#打乱顺序
train_set = shuffled_set[0:train_len]
test_set = shuffled_set[-test_len:]
print("训练集长度是:{}".format(len(train_set)))
print("测试集长度是:{}".format(len(test_set)))
for filename in train_set:
this_file = SOURCE + filename
destination = TRAINING + filename
copyfile(this_file, destination)
for filename in test_set:
this_file = SOURCE + filename
destination = TESTING + filename
copyfile(this_file, destination)
# YOUR CODE ENDS HERE
def create_dir(file_dir):
if os.path.exists(file_dir):
print('true')
#os.rmdir(file_dir)
shutil.rmtree(file_dir)#删除再建立
os.makedirs(file_dir)
else:
os.makedirs(file_dir)
#函数调用
CAT_SOURCE_DIR = "F:/tmp/PetImages/Cat/"
TRAINING_CATS_DIR = "F:/tmp/cats-and-dogs/train/cats/"
TESTING_CATS_DIR = "F:/tmp/cats-and-dogs/test/cats/"
DOG_SOURCE_DIR = "F:/tmp/PetImages/Dog/"
TRAINING_DOGS_DIR = "F:/tmp/cats-and-dogs/train/dogs/"
TESTING_DOGS_DIR = "F:/tmp/cats-and-dogs/test/dogs/"
create_dir(TRAINING_CATS_DIR)
create_dir(TESTING_CATS_DIR)
create_dir(TRAINING_DOGS_DIR)
create_dir(TESTING_CATS_DIR)
split_size = 0.9
split_data(CAT_SOURCE_DIR, TRAINING_CATS_DIR, TESTING_CATS_DIR, split_size)
split_data(DOG_SOURCE_DIR, TRAINING_DOGS_DIR, TESTING_DOGS_DIR, split_size)
# Expected output
# 666.jpg is zero length, so ignoring
# 11702.jpg is zero length, so ignoring
产生的结果:
继续利用os库,查看图片的数量(说句实话,我曾经傻傻的文件扔在jupyter notebook的工作空间里,由于图片太多,直接爆开,推荐大家还是扔在别的地方,最起码点开文件夹还能看那些图片)
print(len(os.listdir('F:/tmp/cats-and-dogs/train/cats/')))
print(len(os.listdir('F:/tmp/cats-and-dogs/train/dogs/')))
print(len(os.listdir('F:/tmp/cats-and-dogs/test/cats/')))
print(len(os.listdir('F:/tmp/cats-and-dogs/test/dogs/')))
2.模型的建立(个人感觉,入门最难的就是这一块,你看着这些莫名奇妙的代码,就感觉崩塌了!!!)
-
关于代码部分,以前没怎么接触过这些库,一开始都是蒙的,其实初学需要知道的是原理,对于代码原理的讲解会放到后面的感想。
-
卷积神经网络的建立和全连接网络
#训练模型,三层卷积和全连接
model = tf.keras.models.Sequential([
# 卷积网络
tf.keras.layers.Conv2D(16,(3,3), activation='relu',input_shape=(150,150,3)),
tf.keras.layers.MaxPool2D(2,2),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
#全连接开始
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer=RMSprop(lr=0.001), loss='binary_crossentropy', metrics=['acc'])
#0.01学习步长初始化为0.01,后续会自动增加
model.summary()#summary函数是用来看神经网络建立的可视化
- 数据的归一化(这个还算好理解,可能代码不是很懂,但是原理不难)
TRAINING_DIR = 'F:/tmp/cats-and-dogs/train/'
train_datagen = ImageDataGenerator(rescale = 1.0/255.)
train_generator = train_datagen.flow_from_directory(TRAINING_DIR,
batch_size=100,
class_mode='binary',
target_size=(150, 150))
VALIDATION_DIR = 'F:/tmp/cats-and-dogs/test/'
validation_datagen = ImageDataGenerator(rescale=1.0/255.)
validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,
batch_size=100,
class_mode='binary',
target_size=(150,150))
- 训练开始(没想到吧,前面写了这么一大堆,训练就那么一句话)
history = model.fit_generator(train_generator,
epochs=2,
verbose=1,
validation_data=validation_generator)
3.查看训练过程中的准确度和损失率的变化
# PLOT LOSS AND ACCURACY
%matplotlib inline
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
#-----------------------------------------------------------
# Retrieve a list of list results on training and test data
# sets for each training epoch
#-----------------------------------------------------------
acc=history.history['acc']
val_acc=history.history['val_acc']
loss=history.history['loss']
val_loss=history.history['val_loss']
epochs=range(len(acc)) # Get number of epochs
#------------------------------------------------
# Plot training and validation accuracy per epoch
#------------------------------------------------
plt.plot(epochs, acc, 'r', "Training Accuracy")
plt.plot(epochs, val_acc, 'b', "Validation Accuracy")
plt.title('Training and validation accuracy')
plt.figure()
#------------------------------------------------
# Plot training and validation loss per epoch
#------------------------------------------------
plt.plot(epochs, loss, 'r', "Training Loss")
plt.plot(epochs, val_loss, 'b', "Validation Loss")
plt.title('Training and validation loss')
一些感想
-
其实,流程走完后,会发现除了模型建立这一块,其他的代码百度一下就都知道啥意思,偏偏难就难在这块部分。
-
图片构成:首先你要了解一个图片图像的构成,RGB三原色。你把图片理解为一个二维数组,就行了:
-
归一化:就是将里面每一个值/255.0,转换为0-1之间即可。这么做的原因很简单,就是方便计算,提高计算速率,如果阔以,你不除以255,看看相同的训练次数要跑多久。
-
上述整个程序的流程:
-
卷积神经网络(按照个人理解):其中最大的特点就是减小数据量,增强数据特征。以代码为例:
tf.keras.layers.Conv2D(16,(3,3), activation='relu',input_shape=(150,150,3)),
tf.keras.layers.MaxPool2D(2,2),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
第一个参数:(16,(3,3))就是内核个数为16,内核长宽为33,作为过滤的作用。
第二个参数:'relu’就是算法,将特征值强化,过滤无用值。
第三个参数:input_shape,输入图片大小,150150,图片个数:3(我看不懂百度的意思,按照自己的理解来)
Maxpool:强化特征值
- 全连接网络:
以代码为例子:
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
Flatten:就是规定输入,将数据一维化。里面参数很多,如果上面有卷积网络,且里面没参数,默认是上一层的长*宽 * 个数(也是高度)。
Dense:神经层,反正就是跟训练精度有关,两层一个是用来计算特征,一个用来输出。其中的算法,就不做讨论。
-
初学的疑惑:
看了一会,大致是了解识图训练的流程,其中最重要的是模型的建立。理解逻辑不难,但是要搞清楚为什么用这个算法,用三次卷积网络,这是我未来的目标。 -
题外话:关于卷积神经网络和归一化,这两个东西为什么要用,首先一个问题就是减少运算量,哪怕就训练两次,对于12500的数据量,也要训练接近半小时,不信的话阔以试试。