日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

openmv 神经网络 超出内存_openmv caffe专栏 1

發(fā)布時間:2024/1/1 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 openmv 神经网络 超出内存_openmv caffe专栏 1 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本專欄參考的原作者文章聲明如下。

PS:本專欄對原作者的文章存在適當?shù)男薷呐c補充,使之更適合本作者所闡述的訓練要求!如有侵權,請聯(lián)系13512076879@163.com。

————————————————

版權聲明:本文為CSDN博主「欣欣以向榮」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權協(xié)議,轉載請附上原文出處鏈接及本聲明。

————————————————

1. caffe框架下openmv的訓練步驟

目前 OPenMV 只提供Caffe模型到network網絡的轉換,未來可能會支持TensorFlow,但目前不行。通過Caffe框架學習,我們最終的目標肯定是得到 ******.network?的網絡庫文件

訓練網絡的主要步驟如下:

配置環(huán)境,安裝Caffe

采集數(shù)據集

訓練網絡

量化模型

將模型轉換為二進制格式

在OPenMV上部署模型

運行網絡

故障排除

2.caffe環(huán)境的搭建(以本文環(huán)境為例介紹)

windows 10

python 2.7

pycharm

vs2013

openmv cam h4

openmv ide

3.vs2013 編譯caffe

4.制作數(shù)據集

由于原文章之前訓練使用的數(shù)據集為64*64,然而這種方法訓練得到的network模型對于openmv來說太大,會造成堆內存溢出,無法運行。

故本文使用數(shù)據集為32*32.

本文使用的數(shù)據集為使用畫圖板制作,并經過一些數(shù)據處理方法,使得數(shù)據集更加豐富。

制作步驟:

4.1.使用以下代碼新建文件夾保存原始數(shù)據(E:/pydoc/blog/為本文程序根目錄? ?E:/pydoc/blog/為本文程序根目錄? ?E:/pydoc/blog/為本文程序根目錄)

importos, sysdefgenDir():

base= 'E:/pydoc/blog/MY_numbers/'i=0

name=['ZERO','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']for j in range(10):

file_name= base+name[i]

os.mkdir(file_name)

i=i+1genDir()

結果如圖:

4.2. 使用以下代碼新建文件夾保存擴展數(shù)據:

importos, sysdefgenDir():

base= 'E:/pydoc/blog/MY_numbers/'i=0

name=['ZERO','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']for j in range(10):

file_name= base+str(i)+'_'+name[i]

os.mkdir(file_name)

i=i+1genDir()

結果如圖:

4.3 制作原始數(shù)據集.

利用畫圖板制作手寫體數(shù)據集,0-9每個5張圖片,大小為32*32.

打開畫圖板

將這些圖片對應地保存到./MY_numbers/ZERO(ONE,TWO,···,NINE)

4.4.使用以下代碼擴展數(shù)據集,代碼保存到根目錄,命名為augment_images.py。

importos, sysimportargparseimportrandomimportcv2importnumpy as npimportimgaug as iafrom imgaug importaugmenters as iaafrom tqdm importtqdmdefmain():#CMD args parser

parser = argparse.ArgumentParser(description='Augment image datasets')

parser.add_argument("--input", action = "store", help = "Input images dir")

parser.add_argument("--output", action = "store", help = "Output images dir")

parser.add_argument("--count", action = "store", help = "Number of augmented sets to make", type=int, default=1)#Parse CMD args

args =parser.parse_args()if (args.input == None or args.output ==None):

parser.print_help()

sys.exit(1)

ia.seed(1)

paths=os.listdir(args.input)for x inrange(args.count):

seq=iaa.Sequential([

iaa.Fliplr(0.5), #horizontal flips

#Small gaussian blur with random sigma between 0 and 0.5.

#But we only blur about 50% of all images.

iaa.Sometimes(0.5,

iaa.GaussianBlur(sigma=(0, 0.2))

),#Add gaussian noise.

#For 50% of all images, we sample the noise once per pixel.

#For the other 50% of all images, we sample the noise per pixel AND

#channel. This can change the color (not only brightness) of the pixels.

iaa.Sometimes(0.5,

iaa.AdditiveGaussianNoise(

loc=0, scale=(0.0, 0.005*255), per_channel=0.5)

),#Make some images brighter and some darker.

#In 20% of all cases, we sample the multiplier once per channel,

#which can end up changing the color of the images.

iaa.Sometimes(0.5,

iaa.Multiply((0.8, 1.2), per_channel=0.0),

),#Apply affine transformations to each image.

#Scale/zoom images.

iaa.Sometimes(0.5,

iaa.Affine(

rotate=(-20, 20),

),

),#Translate/move images.

iaa.Sometimes(0.5,

iaa.Affine(

scale={"x": (0.8, 1.2), "y": (0.8, 1.2)},

),

),#Rotate images.

iaa.Sometimes(0.5,

iaa.Affine(

translate_percent={"x": (-0.1, 0.1), "y": (-0.1, 0.1)},

),

),

], random_order=True) #apply augmenters in random order

print("Augmenting images set %d/%d"%(x+1, args.count))for i intqdm(xrange(len(paths))):

img= cv2.imread(args.input+'/'+paths[i], cv2.IMREAD_GRAYSCALE)

img=seq.augment_image(img)

f=os.path.splitext(paths[i])

cv2.imwrite(args.output+'/'+f[0] + '_aug%d'%(x) + f[1], img)print('Finished processing all images\n')if __name__ == '__main__':

main()

4.5. 使用批處理腳本運行augment_images.py,命名為augment_pic.bat。

python augment_images.py --input MY_numbers/ZERO/ --output MY_numbers/0_ZERO/ --count 20echo.

python augment_images.py--input MY_numbers/ONE/ --output MY_numbers/1_ONE/ --count 20echo.

python augment_images.py--input MY_numbers/TWO/ --output MY_numbers/2_TWO/ --count 20echo.

python augment_images.py--input MY_numbers/THREE/ --output MY_numbers/3_THREE/ --count 20echo.

python augment_images.py--input MY_numbers/FOUR/ --output MY_numbers/4_FOUR/ --count 20echo.

python augment_images.py--input MY_numbers/FIVE/ --output MY_numbers/5_FIVE/ --count 20echo.

python augment_images.py--input MY_numbers/SIX/ --output MY_numbers/6_SIX/ --count 20echo.

python augment_images.py--input MY_numbers/SEVEN/ --output MY_numbers/7_SEVEN/ --count 20echo.

python augment_images.py--input MY_numbers/EIGHT/ --output MY_numbers/8_EIGHT/ --count 20echo.

python augment_images.py--input MY_numbers/NINE/ --output MY_numbers/9_NINE/ --count 20pause

結果如下:

4.6 根目錄新建文件./blog/data.將擴展數(shù)據文件夾拷貝到data文件夾下。

4.7 在./blog目錄下,按住shift,鼠標右鍵打開powershell窗口,輸入tree命令,文件結構如下:

4.8 至此,數(shù)據集制作完畢。

5. 制作數(shù)據標簽。

5.1 制作lmdb標簽

5.1.1 新建create_labels.py 文件,代碼如下:

# coding=utf-8

importos, sysimportargparseimportrandomimportnumpy as npfrom tqdm importtqdmimporttimeimportshutildefshuffle_in_unison(a, b):assert len(a) ==len(b)

shuffled_a= np.empty(a.shape, dtype=a.dtype)

shuffled_b= np.empty(b.shape, dtype=b.dtype)

permutation=np.random.permutation(len(a))for old_index, new_index inenumerate(permutation):

shuffled_a[new_index]=a[old_index]

shuffled_b[new_index]=b[old_index]returnshuffled_a, shuffled_bdefmove_files(input, output):'''Input: 數(shù)據集文件夾,不同分類的數(shù)據存儲在不同子文件夾中

Output: 輸出的所有文件,文件命名格式為 class_number.jpg; 輸出必須是絕對路徑'''index= -1

for root, dirs, files inos.walk(input):if index != -1:print 'Working with path', rootprint 'Path index', index

filenum=0for file in (files if index == -1 elsetqdm(files)):

fileName, fileExtension=os.path.splitext(file)if fileExtension == '.jpg' or fileExtension == '.JPG' or fileExtension == '.png' or fileExtension == '.PNG':

full_path=os.path.join(root, file)#print full_path

if(os.path.isfile(full_path)):

file= os.path.basename(os.path.normpath(root)) + str(filenum) +fileExtensiontry:

test= int(file.split('_')[0])except:

file= str(index) + '_' +file#print os.path.join(output, file)

shutil.copy(full_path, os.path.join(output, file))

filenum+= 1index+= 1

defcreate_text_file(input_path, percentage):'''為 Caffe 創(chuàng)建 train.txt 和 val.txt 文件'''images, labels=[], []

os.chdir(input_path)for item in os.listdir('.'):if not os.path.isfile(os.path.join('.', item)):continue

try:

label= int(item.split('_')[0])

images.append(item)

labels.append(label)except:continueimages=np.array(images)

labels=np.array(labels)

images, labels=shuffle_in_unison(images, labels)

X_train= images[0:int(len(images) *percentage)]

y_train= labels[0:int(len(labels) *percentage)]

X_test= images[int(len(images) *percentage):]

y_test= labels[int(len(labels) *percentage):]

os.chdir('..')

trainfile= open("train.txt", "w")for i, l inzip(X_train, y_train):

trainfile.write(i+ " " + str(l) + "\n")

testfile= open("test.txt", "w")for i, l inzip(X_test, y_test):

testfile.write(i+ " " + str(l) + "\n")

trainfile.close()

testfile.close()defmain():#CMD 指令參數(shù)

parser = argparse.ArgumentParser(description='Create label files for an image dataset')

parser.add_argument("--input", action = "store", help = "Input images dir")

parser.add_argument("--output", action = "store", help = "Output images dir")

parser.add_argument("--percentage", action = "store", help = "Test/Train split", type=float, default=0.85)#測試數(shù)據占訓練數(shù)據的比重

#Parse CMD args

args =parser.parse_args()if (args.input == None or args.output ==None):

parser.print_help()

sys.exit(1)

move_files(args.input, args.output)

create_text_file(args.output, args.percentage)print('Finished processing all images\n')if __name__ == '__main__':

main()

5.1.2 新建文件夾./blog/lmdbin,制作批處理腳本create_lists.bat.

python create_labels.py --input data/ --output lmdbin/

pause

運行腳本,根目錄會生成兩個文件?train.txt 和 test.txt:

現(xiàn)在已經得到了訓練數(shù)據的清單

5.1.3 生成lmdb

生成LMDB格式數(shù)據需要使用Caffe自帶的函數(shù) convert_imageset,所以這些函數(shù)運行需要在編譯好地caffe文件夾下運行,否則會報錯!!!

函數(shù)介紹:

convert_imageset [FLAGS] ROOTFOLDER/ LISTFILE DB_NAME

FLAGS這個參數(shù)組的內容:-gray: 是否以灰度圖的方式打開圖片。程序調用opencv庫中的imread()函數(shù)來打開圖片,默認為false-shuffle: 是否隨機打亂圖片順序。默認為false-backend:需要轉換成的db文件格式,可選為leveldb或lmdb,默認為lmdb-resize_width/resize_height: 改變圖片的大小。在運行中,要求所有圖片的尺寸一致,因此需要改變圖片大小。 程序調用opencv庫的resize()函數(shù)來對圖片放大縮小,默認為0,不改變-check_size: 檢查所有的數(shù)據是否有相同的尺寸。默認為false,不檢查-encoded: 是否將原圖片編碼放入最終的數(shù)據中,默認為false-encode_type: 與前一個參數(shù)對應,將圖片編碼為哪一個格式:‘png','jpg'......

————————————————

版權聲明:本文為CSDN博主「欣欣以向榮」的原創(chuàng)文章,遵循 CC4.0 BY-SA 版權協(xié)議,轉載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/qq_37783617/article/details/96841981

ROOTFOLDER/: 圖片存放的絕對路徑,lmdbin的路徑

LISTFILE: 圖片文件列表清單,一般為一個txt文件,一行一張圖片

DB_NAME: 最終生成的db文件存放目錄

執(zhí)行腳本文件:(腳本需要在./caffe-master/Build/x64/Release/下)

convert_imageset --shuffle E:/pydoc/blog/lmdbin/ E:/pydoc/blog/train.txtE:/pydoc/blog/train_lmdb

echo.convert_imageset --shuffle E:/pydoc/blog/lmdbin/ E:/pydoc/blog/test.txt E:/pydoc/blog/test_lmdb

根目錄里生成了test_lmdb文件夾和train_lmdb文件夾

上述兩個文件夾下各生成兩個數(shù)據包:

到此,lmdb的數(shù)據集準備完成!

如果有需要,可以執(zhí)行腳本生成均值文件:

優(yōu)點:圖片減去均值再訓練,會提高訓練速度和精度。因此,一般都會有這個操作。

但是必須保證所有圖片的規(guī)格大小一致

執(zhí)行腳本:(腳本需要在./caffe-master/Build/x64/Release/下)

compute_image_mean -backend=lmdb E:/pydoc/blog/train_lmdb mean.binaryproto

pause

6.訓練神經網絡

6.1 準備prototxt文件

下載openmv-master,解壓到./blog文件夾下。

打開openmv-master\ml\cmsisnn\models\lenet,可以看到:

lenet.network (適用于OPenMV的神經網絡,是一個二進制文件)

lenet_solver.prototxt (供Caffe使用的配置訓練參數(shù)的文件)

lenet_train_test.prototxt (網絡各層訓練和測試的參數(shù))

test.sh (Linux腳本文件,用于測試模型)

train.sh(Linux腳本文件,用于訓練模型)

我們把后四個文件拷貝到要網絡的根目錄下備用!!!

6.2 修改訓練參數(shù)

6.2.1打開lenet_solver.prototxt文件

修改紅圈的幾處地方:

第一處:net: "[lenet_train_test.prototxt文件的存放路徑]"

第二處:test_iter: [該數(shù)值表示測試每次數(shù)據的量]=測試數(shù)據總量/batch_size

比如我們有150個測試數(shù)據,每次測試10個就只需要測試15次,修改test_iter:15

第三處:最大迭代次數(shù)(根據數(shù)據集大小設定) 過小精度低,過大會導致震蕩

第四處:快照次數(shù),根據訓練數(shù)據集大小設定

第五處:快照保存的地址

第六處:如果之前caffe編譯是在CPU環(huán)境下,此處改為CPU。

6.2.2打開lenet_train_test.prototxt文件

name: "LeNet"layer {

name:"data"type:"Data"top:"data"top:"label"include {

phase: TRAIN

}

transform_param {

scale:0.00390625mean_file:"mean.binaryproto" //沒有均值文件的刪除該行

}

data_param {

source:"train_lmdb" //訓練用lmdb文件夾的相對地址

batch_size:32 //訓練間隔,一般為64,我的數(shù)據集小,使用32

backend: LMDB

}

}

layer {

name:"data"type:"Data"top:"data"top:"label"include {

phase: TEST

}

transform_param {

scale:0.00390625mean_file:"mean.binaryproto" //沒有均值文件的刪除該行

}

data_param {

source:"test_lmdb" //測試用lmdb文件夾的相對地址

batch_size:10 //測試間隔,與前一個文件中的test_iter有對應關系 10*15=150(測試數(shù)量)

backend: LMDB//數(shù)據集存儲結構

}

}

layer {

name:"conv1"type:"Convolution"bottom:"data"top:"conv1"param {

lr_mult:1}

param {

lr_mult:2}

convolution_param {

num_output:20kernel_size:5 //如果圖片規(guī)格小,可以適當減小卷積核的大小

stride:1weight_filler {

type:"xavier"}

bias_filler {

type:"constant"}

}

}

layer {

name:"pool1"type:"Pooling"bottom:"conv1"top:"pool1"pooling_param {

pool: MAX

kernel_size:2stride:2}

}

layer {

name:"conv2"type:"Convolution"bottom:"pool1"top:"conv2"param {

lr_mult:1}

param {

lr_mult:2}

convolution_param {

num_output:50kernel_size:5 //如果圖片規(guī)格小,可以適當減小卷積核的大小

stride:1weight_filler {

type:"xavier"}

bias_filler {

type:"constant"}

}

}

layer {

name:"pool2"type:"Pooling"bottom:"conv2"top:"pool2"pooling_param {

pool: MAX

kernel_size:2stride:2}

}

layer {

name:"ip1"type:"InnerProduct"bottom:"pool2"top:"ip1"param {

lr_mult:1}

param {

lr_mult:2}

inner_product_param {

num_output:100weight_filler {

type:"xavier"}

bias_filler {

type:"constant"}

}

}

layer {

name:"relu1"type:"ReLU"bottom:"ip1"top:"ip1"}

layer {

name:"ip2"type:"InnerProduct"bottom:"ip1"top:"ip2"param {

lr_mult:1}

param {

lr_mult:2}

inner_product_param {

num_output:10weight_filler {

type:"xavier"}

bias_filler {

type:"constant"}

}

}

layer {

name:"accuracy"type:"Accuracy"bottom:"ip2"bottom:"label"top:"accuracy"include {

phase: TEST

}

}

layer {

name:"loss"type:"SoftmaxWithLoss"bottom:"ip2"bottom:"label"top:"loss"}

6.3 訓練模型

6.3.1 編寫 train.bat : (腳本需要在./caffe-master/Build/x64/Release/下)

caffe train --solver=E:/pydoc/blog/lenet_solver.prototxt

pause

6.3.2?編寫 test.bat:(腳本需要在./caffe-master/Build/x64/Release/下)

caffe test --model=E:/pydoc/blog/lenet_train_test.prototxt --weights=E:/pydoc/blog/lenet/_iter_500.caffemodel

pause

輸出:

可見,模型準確率為:87.8%。

7.生成openmv二進制文件。

7.1 打開./openmv-master/openmv-master/ml/cmsisnn,nn_quantizer.py?和?nn_convert.py?,我們將這兩個腳本拷貝到根目錄./blog下

7.2 編寫批處理文件:

python nn_quantizer.py --cpu --model E:/pydoc/blog/lenet_train_test.prototxt --weights E:/pydoc/blog/lenet/_iter_500.caffemodel --save E:/pydoc/blog/lenet/output.pkl

pause

7.3 生成二進制文件

使用 OpenMV NN 轉換器腳本將模型轉換為二進制格式,可由 OpenMV Cam 運行。該轉換器腳本會輸出每個層類型的代碼,后跟該層的維度和權重。

在 OpenMV Cam 上,固件讀取該二進制文件,并使用鏈表數(shù)據結構在內存中構建網絡。

編寫批處理腳本

python nn_convert.py --model E:/pydoc/blog/lenet/output.pkl --mean E:/pydoc/blog/mean.binaryproto --output E:/pydoc/blog/lenet/output.network

pause

輸出:

至此:全部結束!!!

生成network后如何在openmv上運行,請參考openmv視頻教程:https://singtown.com/learn/50543/

總結

以上是生活随笔為你收集整理的openmv 神经网络 超出内存_openmv caffe专栏 1的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。