> 原文博客:Doi技術團隊
鏈接地址:https://blog.doiduoyi.com/authors/1584446358138
初心:記錄優秀的Doi技術團隊學習經歷
*本篇文章基於 PaddlePaddle 0.11.0、Python 2.7
數據集介紹¶
如果我們要訓練自己的數據集的話,就需要先建立圖像列表文件,下面的代碼是Myreader.py讀取圖像數據集的一部分,從這些代碼中可以看出,圖像列表中,圖像的路徑和標籤是以\t來分割的,所以我們在生成這個列表的時候,使用\t就可以了.
def train_reader(self,train_list, buffered_size=1024):
def reader():
with open(train_list, 'r') as f:
lines = [line.strip() for line in f]
for line in lines:
img_path, lab = line.strip().split('\t')
yield img_path, int(lab)
return paddle.reader.xmap_readers(self.train_mapper, reader,
cpu_count(), buffered_size)
生成的圖像列表的結構是這樣的:
../images/vegetables/lotus_root/1515827057517.jpg 2
../images/vegetables/lotus_root/1515827057582.jpg 2
../images/vegetables/lotus_root/1515827057616.jpg 2
../images/vegetables/lettuce/1515827015922.jpg 1
../images/vegetables/lettuce/1515827015983.jpg 1
../images/vegetables/lettuce/1515827016045.jpg 1
../images/vegetables/cuke/1515827008337.jpg 0
../images/vegetables/cuke/1515827008370.jpg 0
../images/vegetables/cuke/1515827008402.jpg 0
生成圖像列表¶
所以我們要編寫一個CreateDataList.py程序可以爲我們生成這樣的圖像列表
在這個程序中,我們只要把一個大類的文件夾路徑傳進去就可以了,該程序會把裏面的每個小類別都迭代,生成固定格式的列表.比如我們把蔬菜類別的根目錄傳進去../images/vegetables
# coding=utf-8
import os
import json
class CreateDataList:
def __init__(self):
pass
def createDataList(self, data_root_path):
# # 把生產的數據列表都放在自己的總類別文件夾中
data_list_path = ''
# 所有類別的信息
class_detail = []
# 獲取所有類別
class_dirs = os.listdir(data_root_path)
# 類別標籤
class_label = 0
# 獲取總類別的名稱
father_paths = data_root_path.split('/')
while True:
if father_paths[father_paths.__len__() - 1] == '':
del father_paths[father_paths.__len__() - 1]
else:
break
father_path = father_paths[father_paths.__len__() - 1]
all_class_images = 0
# 讀取每個類別
for class_dir in class_dirs:
# 每個類別的信息
class_detail_list = {}
test_sum = 0
trainer_sum = 0
# 把生產的數據列表都放在自己的總類別文件夾中
data_list_path = "../data/%s/" % father_path
# 統計每個類別有多少張圖片
class_sum = 0
# 獲取類別路徑
path = data_root_path + "/" + class_dir
# 獲取所有圖片
img_paths = os.listdir(path)
for img_path in img_paths:
# 每張圖片的路徑
name_path = path + '/' + img_path
# 如果不存在這個文件夾,就創建
isexist = os.path.exists(data_list_path)
if not isexist:
os.makedirs(data_list_path)
# 每10張圖片取一個做測試數據
if class_sum % 10 == 0:
test_sum += 1
with open(data_list_path + "test.list", 'a') as f:
f.write(name_path + "\t%d" % class_label + "\n")
else:
trainer_sum += 1
with open(data_list_path + "trainer.list", 'a') as f:
f.write(name_path + "\t%d" % class_label + "\n")
class_sum += 1
all_class_images += 1
class_label += 1
# 說明的json文件的class_detail數據
class_detail_list['class_name'] = class_dir
class_detail_list['class_label'] = class_label
class_detail_list['class_test_images'] = test_sum
class_detail_list['class_trainer_images'] = trainer_sum
class_detail.append(class_detail_list)
# 獲取類別數量
all_class_sum = class_dirs.__len__()
# 說明的json文件信息
readjson = {}
readjson['all_class_name'] = father_path
readjson['all_class_sum'] = all_class_sum
readjson['all_class_images'] = all_class_images
readjson['class_detail'] = class_detail
jsons = json.dumps(readjson, sort_keys=True, indent=4, separators=(',', ': '))
with open(data_list_path + "readme.json",'w') as f:
f.write(jsons)
if __name__ == '__main__':
createDataList = CreateDataList()
createDataList.createDataList('../images/vegetables')
運行這個程序之後,會生成在data文件夾中生成一個單獨的大類文件夾,比如我們這次是使用到蔬菜類,所以我生成一個vegetables文件夾,在這個文件夾下有3個文件:
|文件名|作用|
|:—:|:—:|
|trainer.list|用於訓練的圖像列表|
|test.list|用於測試的圖像列表|
|readme.json|該數據集的json格式的說明,方便以後使用|
readme.json文件的格式如下,可以很清楚看到整個數據的圖像數量,總類別名稱和類別數量,還有每個類對應的標籤,類別的名字,該類別的測試數據和訓練數據的數量:
{
"all_class_images": 3300,
"all_class_name": "vegetables",
"all_class_sum": 3,
"class_detail": [
{
"class_label": 1,
"class_name": "cuke",
"class_test_images": 110,
"class_trainer_images": 990
},
{
"class_label": 2,
"class_name": "lettuce",
"class_test_images": 110,
"class_trainer_images": 990
},
{
"class_label": 3,
"class_name": "lotus_root",
"class_test_images": 110,
"class_trainer_images": 990
}
]
}
讀取數據¶
通過MyReader.py這個程序可以將上一部分的圖像列表讀取,生成訓練和測試使用的reader,在生成reader前,要傳入一個圖像的大小,PaddlePaddle會幫我們按照這個大小隨機裁剪一個方形的圖像,這是種隨機裁剪也是數據增強的一種方式.
from multiprocessing import cpu_count
import paddle.v2 as paddle
class MyReader:
def __init__(self,imageSize):
self.imageSize = imageSize
def train_mapper(self,sample):
'''
map image path to type needed by model input layer for the training set
'''
img, label = sample
img = paddle.image.load_image(img)
img = paddle.image.simple_transform(img, 70, self.imageSize, True)
return img.flatten().astype('float32'), label
def test_mapper(self,sample):
'''
map image path to type needed by model input layer for the test set
'''
img, label = sample
img = paddle.image.load_image(img)
img = paddle.image.simple_transform(img, 70, self.imageSize, False)
return img.flatten().astype('float32'), label
def train_reader(self,train_list, buffered_size=1024):
def reader():
with open(train_list, 'r') as f:
lines = [line.strip() for line in f]
for line in lines:
img_path, lab = line.strip().split('\t')
yield img_path, int(lab)
return paddle.reader.xmap_readers(self.train_mapper, reader,
cpu_count(), buffered_size)
def test_reader(self,test_list, buffered_size=1024):
def reader():
with open(test_list, 'r') as f:
lines = [line.strip() for line in f]
for line in lines:
img_path, lab = line.strip().split('\t')
yield img_path, int(lab)
return paddle.reader.xmap_readers(self.test_mapper, reader,
cpu_count(), buffered_size)
定義神經網絡¶
編寫一個vgg.py來定義VGG神經網絡,這裏使用的是VGG神經網絡,跟上一篇文章用到的VGG又有一點不同,這裏可以看到conv_with_batchnorm=False,我是把BN關閉了,這是因爲啓用BN層的同時,也會使用Dropout層,因爲數據集比較小,再使用Dropout就更小了,導致模型無法收斂。如果讀者一定要啓動BN層的話,可以單獨關閉Dropout,把drop_rate全部設置爲0。如果數據集大的話,就可以不用這樣處理。
# coding:utf-8
import paddle.v2 as paddle
def vgg_bn_drop(datadim, type_size):
# 獲取輸入數據模式
image = paddle.layer.data(name="image",
type=paddle.data_type.dense_vector(datadim))
def conv_block(ipt, num_filter, groups, dropouts, num_channels=None):
return paddle.networks.img_conv_group(
input=ipt,
num_channels=num_channels,
pool_size=2,
pool_stride=2,
conv_num_filter=[num_filter] * groups,
conv_filter_size=3,
conv_act=paddle.activation.Relu(),
conv_with_batchnorm=False,
conv_batchnorm_drop_rate=dropouts,
pool_type=paddle.pooling.Max())
conv1 = conv_block(image, 64, 2, [0.3, 0], 3)
conv2 = conv_block(conv1, 128, 2, [0.4, 0])
conv3 = conv_block(conv2, 256, 3, [0.4, 0.4, 0])
conv4 = conv_block(conv3, 512, 3, [0.4, 0.4, 0])
conv5 = conv_block(conv4, 512, 3, [0.4, 0.4, 0])
drop = paddle.layer.dropout(input=conv5, dropout_rate=0.5)
fc1 = paddle.layer.fc(input=drop, size=512, act=paddle.activation.Linear())
bn = paddle.layer.batch_norm(input=fc1,
act=paddle.activation.Relu(),
layer_attr=paddle.attr.Extra(drop_rate=0.5))
fc2 = paddle.layer.fc(input=bn, size=512, act=paddle.activation.Linear())
# 通過Softmax獲得分類器
out = paddle.layer.fc(input=fc2,
size=type_size,
act=paddle.activation.Softmax())
return out
使用PaddlePaddle開始訓練¶
編寫train.py文件訓練模型。
導入依賴包¶
首先要先導入依賴包,其中有PaddlePaddle的V2包和上面定義的Myreader.py讀取數據的程序
# coding:utf-8
import os
import sys
import paddle.v2 as paddle
from MyReader import MyReader
from vgg import vgg_bn_drop
初始化Paddle¶
然後我們創建一個類,再在類中創建一個初始化函數,在初始化函數中來初始化我們的PaddlePaddle
class PaddleUtil:
def __init__(self):
# 初始化paddpaddle,只是用CPU,把GPU關閉
paddle.init(use_gpu=False, trainer_count=2)
獲取參數¶
該函數可以通過輸入是否是參數文件路徑,或者是損失函數,如果是參數文件路徑,就使用之前訓練好的參數生產參數.如果不傳入參數文件路徑,那就使用傳入的損失函數生成參數
def get_parameters(self, parameters_path=None, cost=None):
if not parameters_path:
# 使用cost創建parameters
if not cost:
raise NameError('請輸入cost參數')
else:
# 根據損失函數創建參數
parameters = paddle.parameters.create(cost)
print "cost"
return parameters
else:
# 使用之前訓練好的參數
try:
# 使用訓練好的參數
with open(parameters_path, 'r') as f:
parameters = paddle.parameters.Parameters.from_tar(f)
print "使用parameters"
return parameters
except Exception as e:
raise NameError("你的參數文件錯誤,具體問題是:%s" % e)
創建訓練器¶
創建訓練器要3個參數,分別是損失函數,參數,優化方法.通過圖像的標籤信息和分類器生成損失函數.參數可以選擇是使用之前訓練好的參數,然後在此基礎上再進行訓練,又或者是使用損失函數生成初始化參數.然後再生成優化方法.就可以創建一個訓練器了.
# datadim 數據大小
def get_trainer(self, datadim, type_size, parameters_path):
# 獲得圖片對於的信息標籤
label = paddle.layer.data(name="label",
type=paddle.data_type.integer_value(type_size))
# 獲取全連接層,也就是分類器
out = vgg_bn_drop(datadim=datadim, type_size=type_size)
# 獲得損失函數
cost = paddle.layer.classification_cost(input=out, label=label)
# 獲得參數
if not parameters_path:
parameters = self.get_parameters(cost=cost)
else:
parameters = self.get_parameters(parameters_path=parameters_path)
'''
定義優化方法
learning_rate 迭代的速度
momentum 跟前面動量優化的比例
regularzation 正則化,防止過擬合
'''
optimizer = paddle.optimizer.Momentum(
momentum=0.9,
regularization=paddle.optimizer.L2Regularization(rate=0.0005 * 128),
learning_rate=0.001 / 128,
learning_rate_decay_a=0.1,
learning_rate_decay_b=128000 * 35,
learning_rate_schedule="discexp", )
'''
創建訓練器
cost 分類器
parameters 訓練參數,可以通過創建,也可以使用之前訓練好的參數
update_equation 優化方法
'''
trainer = paddle.trainer.SGD(cost=cost,
parameters=parameters,
update_equation=optimizer)
return trainer
開始訓練¶
要啓動訓練要4個參數,分別是訓練數據,訓練的輪數,訓練過程中的事件處理,輸入數據和標籤的對應關係.
訓練數據:這次的訓練數據是我們自定義的數據集.
訓練輪數:表示我們要訓練多少輪,次數越多準確率越高,最終會穩定在一個固定的準確率上.不得不說的是這個會比MNIST數據集的速度慢很多
事件處理:訓練過程中的一些事件處理,比如會在每個batch打印一次日誌,在每個pass之後保存一下參數和測試一下測試數據集的預測準確率.
輸入數據和標籤的對應關係:說明輸入數據是第0維度,標籤是第1維度
# ***********************開始訓練***************************************
def start_trainer(self, trainer, num_passes, save_parameters_name, trainer_reader, test_reader):
# 獲得數據
reader = paddle.batch(reader=paddle.reader.shuffle(reader=trainer_reader,
buf_size=50000),
batch_size=128)
# 保證保存模型的目錄是存在的
father_path = save_parameters_name[:save_parameters_name.rfind("/")]
if not os.path.exists(father_path):
os.makedirs(father_path)
# 指定每條數據和padd.layer.data的對應關係
feeding = {"image": 0, "label": 1}
# 定義訓練事件
def event_handler(event):
if isinstance(event, paddle.event.EndIteration):
if event.batch_id % 100 == 0:
print "\nPass %d, Batch %d, Cost %f, Error %s" % (
event.pass_id, event.batch_id, event.cost, event.metrics['classification_error_evaluator'])
else:
sys.stdout.write('.')
sys.stdout.flush()
# 每一輪訓練完成之後
if isinstance(event, paddle.event.EndPass):
# 保存訓練好的參數
with open(save_parameters_name, 'w') as f:
trainer.save_parameter_to_tar(f)
# 測試準確率
result = trainer.test(reader=paddle.batch(reader=test_reader,
batch_size=128),
feeding=feeding)
print "\nTest with Pass %d, Classification_Error %s" % (
event.pass_id, result.metrics['classification_error_evaluator'])
'''
開始訓練
reader 訓練數據
num_passes 訓練的輪數
event_handler 訓練的事件,比如在訓練的時候要做一些什麼事情
feeding 說明每條數據和padd.layer.data的對應關係
'''
trainer.train(reader=reader,
num_passes=num_passes,
event_handler=event_handler,
feeding=feeding)
然後在main中調用相應的函數,開始訓練,可以看到通過myReader.train_reader來生成一個reader
if __name__ == '__main__':
# 類別總數
type_size = 3
# 圖片大小
imageSize = 64
# 總的分類名稱
all_class_name = 'fruits'
# 保存的model路徑
parameters_path = "../model/model.tar"
# 數據的大小
datadim = 3 * imageSize * imageSize
paddleUtil = PaddleUtil()
myReader = MyReader(imageSize=imageSize)
# parameters_path設置爲None就使用普通生成參數,
trainer = paddleUtil.get_trainer(datadim=datadim, type_size=type_size, parameters_path=None)
trainer_reader = myReader.train_reader(train_list="../data/%s/trainer.list" % all_class_name)
test_reader = myReader.test_reader(test_list="../data/%s/test.list" % all_class_name)
paddleUtil.start_trainer(trainer=trainer, num_passes=100, save_parameters_name=parameters_path,
trainer_reader=trainer_reader, test_reader=test_reader)
輸出日誌如下:’
Pass 0, Batch 0, Cost 1.162887, Error 0.6171875
.....................
Test with Pass 0, Classification_Error 0.353333324194
提示:如果報以下錯誤:
File "/usr/local/lib/python2.7/dist-packages/paddle/v2/image.py", line 159, in load_image
im = cv2.imread(file, flag)
AttributeError: 'NoneType' object has no attribute 'imread'
解決辦法如下,首先升級以下CV2:
sudo pip install opencv-python -U
然後安裝CV2的庫:
sudo apt install libopencv-dev
使用PaddlePaddle預測¶
編寫一個infer.py來預測我們的數據。
先定義一個獲取模型參數的函數:
def get_parameters(parameters_path):
with open(parameters_path, 'r') as f:
parameters = paddle.parameters.Parameters.from_tar(f)
return parameters
定義預測函數,該函數需要輸入3個參數,
第一個是需要預測的圖像,圖像傳入之後,會經過load_image函數處理,大小會變成32*32大小,訓練是輸入數據的大小一樣.
第二個就是訓練好的參數
第三個是通過神經模型生成的分類器
def to_prediction(image_paths, parameters, out, imageSize):
# 獲得要預測的圖片
test_data = []
for image_path in image_paths:
test_data.append((paddle.image.load_and_transform(image_path, 70, imageSize, False)
.flatten().astype('float32'),))
# 獲得預測結果
probs = paddle.infer(output_layer=out,
parameters=parameters,
input=test_data)
# 處理預測結果
lab = np.argsort(-probs)
# 返回概率最大的值和其對應的概率值
all_result = []
for i in range(0, lab.__len__()):
all_result.append([lab[i][0], probs[i][(lab[i][0])]])
return all_result
然後在main中調用相應的函數,開始預測,這個可以同時傳入多個數據,可以同時預測,最後別忘了在使用PaddlePaddle前初始化PaddlePaddle。
if __name__ == '__main__':
paddle.init(use_gpu=False, trainer_count=2)
# 類別總數
type_size = 3
# 圖片大小
imageSize = 64
# 保存的model路徑
parameters_path = "../model/model.tar"
# 數據的大小
datadim = 3 * imageSize * imageSize
# 添加數據
image_path = []
image_path.append("../images/vegetables/cuke/1515826971850.jpg")
image_path.append("../images/vegetables/lettuce/1515827012863.jpg")
image_path.append("../images/vegetables/lotus_root/1515827059200.jpg")
out = vgg_bn_drop(datadim=datadim, type_size=type_size)
parameters = get_parameters(parameters_path=parameters_path)
all_result = to_prediction(image_paths=image_path, parameters=parameters,
out=out, imageSize=imageSize)
for i in range(0, all_result.__len__()):
print '預測結果爲:%d,可信度爲:%f' % (all_result[i][0], all_result[i][1])
輸出的結果是:
預測結果爲:0,可信度爲:0.699004
預測結果爲:0,可信度爲:0.546674
預測結果爲:2,可信度爲:0.756389
所有代碼¶
train.py,訓練代碼:
# coding:utf-8
import os
import sys
import paddle.v2 as paddle
from MyReader import MyReader
from vgg import vgg_bn_drop
class PaddleUtil:
# ***********************初始化操作***************************************
def __init__(self):
# 初始化paddpaddle,只是用CPU,把GPU關閉
paddle.init(use_gpu=False, trainer_count=2)
# **********************獲取參數***************************************
def get_parameters(self, parameters_path=None, cost=None):
if not parameters_path:
# 使用cost創建parameters
if not cost:
raise NameError('請輸入cost參數')
else:
# 根據損失函數創建參數
parameters = paddle.parameters.create(cost)
print "cost"
return parameters
else:
# 使用之前訓練好的參數
try:
# 使用訓練好的參數
with open(parameters_path, 'r') as f:
parameters = paddle.parameters.Parameters.from_tar(f)
print "使用parameters"
return parameters
except Exception as e:
raise NameError("你的參數文件錯誤,具體問題是:%s" % e)
# ***********************獲取訓練器***************************************
# datadim 數據大小
def get_trainer(self, datadim, type_size, parameters_path):
# 獲得圖片對於的信息標籤
label = paddle.layer.data(name="label",
type=paddle.data_type.integer_value(type_size))
# 獲取全連接層,也就是分類器
out = vgg_bn_drop(datadim=datadim, type_size=type_size)
# 獲得損失函數
cost = paddle.layer.classification_cost(input=out, label=label)
# 獲得參數
if not parameters_path:
parameters = self.get_parameters(cost=cost)
else:
parameters = self.get_parameters(parameters_path=parameters_path)
'''
定義優化方法
learning_rate 迭代的速度
momentum 跟前面動量優化的比例
regularzation 正則化,防止過擬合
'''
optimizer = paddle.optimizer.Momentum(
momentum=0.9,
regularization=paddle.optimizer.L2Regularization(rate=0.0005 * 128),
learning_rate=0.001 / 128,
learning_rate_decay_a=0.1,
learning_rate_decay_b=128000 * 35,
learning_rate_schedule="discexp", )
'''
創建訓練器
cost 分類器
parameters 訓練參數,可以通過創建,也可以使用之前訓練好的參數
update_equation 優化方法
'''
trainer = paddle.trainer.SGD(cost=cost,
parameters=parameters,
update_equation=optimizer)
return trainer
# ***********************開始訓練***************************************
def start_trainer(self, trainer, num_passes, save_parameters_name, trainer_reader, test_reader):
# 獲得數據
reader = paddle.batch(reader=paddle.reader.shuffle(reader=trainer_reader,
buf_size=50000),
batch_size=128)
# 保證保存模型的目錄是存在的
father_path = save_parameters_name[:save_parameters_name.rfind("/")]
if not os.path.exists(father_path):
os.makedirs(father_path)
# 指定每條數據和padd.layer.data的對應關係
feeding = {"image": 0, "label": 1}
# 定義訓練事件
def event_handler(event):
if isinstance(event, paddle.event.EndIteration):
if event.batch_id % 100 == 0:
print "\nPass %d, Batch %d, Cost %f, Error %s" % (
event.pass_id, event.batch_id, event.cost, event.metrics['classification_error_evaluator'])
else:
sys.stdout.write('.')
sys.stdout.flush()
# 每一輪訓練完成之後
if isinstance(event, paddle.event.EndPass):
# 保存訓練好的參數
with open(save_parameters_name, 'w') as f:
trainer.save_parameter_to_tar(f)
# 測試準確率
result = trainer.test(reader=paddle.batch(reader=test_reader,
batch_size=128),
feeding=feeding)
print "\nTest with Pass %d, Classification_Error %s" % (
event.pass_id, result.metrics['classification_error_evaluator'])
'''
開始訓練
reader 訓練數據
num_passes 訓練的輪數
event_handler 訓練的事件,比如在訓練的時候要做一些什麼事情
feeding 說明每條數據和padd.layer.data的對應關係
'''
trainer.train(reader=reader,
num_passes=num_passes,
event_handler=event_handler,
feeding=feeding)
if __name__ == '__main__':
# 類別總數
type_size = 3
# 圖片大小
imageSize = 64
# 總的分類名稱
all_class_name = 'vegetables'
# 保存的model路徑
parameters_path = "../model/model.tar"
# 數據的大小
datadim = 3 * imageSize * imageSize
paddleUtil = PaddleUtil()
# *******************************開始訓練**************************************
myReader = MyReader(imageSize=imageSize)
# # parameters_path設置爲None就使用普通生成參數,
trainer = paddleUtil.get_trainer(datadim=datadim, type_size=type_size, parameters_path=None)
trainer_reader = myReader.train_reader(train_list="../data/%s/trainer.list" % all_class_name)
test_reader = myReader.test_reader(test_list="../data/%s/test.list" % all_class_name)
paddleUtil.start_trainer(trainer=trainer, num_passes=100, save_parameters_name=parameters_path,
trainer_reader=trainer_reader, test_reader=test_reader)
infer.py,預測代碼:
# coding:utf-8
import numpy as np
import paddle.v2 as paddle
from vgg import vgg_bn_drop
# **********************獲取參數***************************************
def get_parameters(parameters_path):
with open(parameters_path, 'r') as f:
parameters = paddle.parameters.Parameters.from_tar(f)
return parameters
# ***********************使用訓練好的參數進行預測***************************************
def to_prediction(image_paths, parameters, out, imageSize):
# 獲得要預測的圖片
test_data = []
for image_path in image_paths:
test_data.append((paddle.image.load_and_transform(image_path, 70, imageSize, False)
.flatten().astype('float32'),))
# 獲得預測結果
probs = paddle.infer(output_layer=out,
parameters=parameters,
input=test_data)
# 處理預測結果
lab = np.argsort(-probs)
# 返回概率最大的值和其對應的概率值
all_result = []
for i in range(0, lab.__len__()):
all_result.append([lab[i][0], probs[i][(lab[i][0])]])
return all_result
if __name__ == '__main__':
paddle.init(use_gpu=False, trainer_count=2)
# 類別總數
type_size = 3
# 圖片大小
imageSize = 64
# 保存的model路徑
parameters_path = "../model/model.tar"
# 數據的大小
datadim = 3 * imageSize * imageSize
# *******************************開始預測**************************************
# 添加數據
image_path = []
image_path.append("../images/vegetables/cuke/1515826971850.jpg")
image_path.append("../images/vegetables/lettuce/1515827012863.jpg")
image_path.append("../images/vegetables/lotus_root/1515827059200.jpg")
out = vgg_bn_drop(datadim=datadim, type_size=type_size)
parameters = get_parameters(parameters_path=parameters_path)
all_result = to_prediction(image_paths=image_path, parameters=parameters,
out=out, imageSize=imageSize)
for i in range(0, all_result.__len__()):
print '預測結果爲:%d,可信度爲:%f' % (all_result[i][0], all_result[i][1])
DownloadImages.py,下載圖片的代碼:
這個程序可以從百度圖片中下載圖片,可以多個類別一起下載,還可以指定下載數量
# -*- coding:utf-8 -*-
import re
import uuid
import requests
import os
class DownloadImages:
def __init__(self,download_max,key_word):
self.download_sum = 0
self.download_max = download_max
self.key_word = key_word
self.save_path = '../images/download/' + key_word
def start_download(self):
self.download_sum = 0
gsm = 80
str_gsm = str(gsm)
pn = 0
if not os.path.exists(self.save_path):
os.makedirs(self.save_path)
while self.download_sum < self.download_max:
str_pn = str(self.download_sum)
url = 'http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&' \
'word=' + self.key_word + '&pn=' + str_pn + '&gsm=' + str_gsm + '&ct=&ic=0&lm=-1&width=0&height=0'
print url
result = requests.get(url)
self.downloadImages(result.text)
print '下載完成'
def downloadImages(self,html):
img_urls = re.findall('"objURL":"(.*?)",', html, re.S)
print '找到關鍵詞:' + self.key_word + '的圖片,現在開始下載圖片...'
for img_url in img_urls:
print '正在下載第' + str(self.download_sum + 1) + '張圖片,圖片地址:' + str(img_url)
try:
pic = requests.get(img_url, timeout=50)
pic_name = self.save_path + '/' + str(uuid.uuid1()) + '.' + str(img_url).split('.')[-1]
with open(pic_name, 'wb') as f:
f.write(pic.content)
self.download_sum += 1
if self.download_sum >= self.download_max:
break
except Exception, e:
print '【錯誤】當前圖片無法下載,%s' % e
continue
if __name__ == '__main__':
key_word_max = input('請輸入你要下載幾個類別:')
key_words = []
for sum in range(key_word_max):
key_words.append(raw_input('請輸入第%s個關鍵字:' % str(sum+1)))
max_sum = input('請輸入每個類別下載的數量:')
for key_word in key_words:
downloadImages = DownloadImages(max_sum, key_word)
downloadImages.start_download()
上一章:《我的PaddlePaddle學習之路》筆記三——CIFAR彩色圖像識別¶
下一章:《我的PaddlePaddle學習之路》筆記五——驗證碼的識別¶
項目代碼¶
GitHub地址:https://github.com/yeyupiaoling/LearnPaddle
參考資料¶
- http://paddlepaddle.org/