python 將Mnist數據集轉為jpg,並按比例/標簽拆分為多個子數據集

achived 2021-08-15 12:58:39 阅读数:797

本文一共[544]字,预计阅读时长:1分钟~
python mnist jpg 比例 拆分

現有條件:Mnist數據集,下載地址:跳轉 下載後的四個.gz文件解壓後放到同一個文件夾下,如:/raw

Step 1:將Mnist數據集轉為jpg圖片(代碼來自這篇博客)

 1 import os  2 from skimage import io  3 import torchvision.datasets.mnist as mnist  4
 5 root='./raw'
 6 train_set = (  7 mnist.read_image_file(os.path.join(root, 'train-images.idx3-ubyte')),  8 mnist.read_label_file(os.path.join(root, 'train-labels.idx1-ubyte'))  9  ) 10 test_set = ( 11 mnist.read_image_file(os.path.join(root, 't10k-images.idx3-ubyte')), 12 mnist.read_label_file(os.path.join(root, 't10k-labels.idx1-ubyte')) 13  ) 14 # print("training set :",train_set[0].size())
15 # print("test set :",test_set[0].size())
16
17 def convert_to_img(train=True): 18 if(train): 19 f=open(root+'train.txt','w') 20 data_path=root+'/train/'
21 if(not os.path.exists(data_path)): 22  os.makedirs(data_path) 23 for i, (img,label) in enumerate(zip(train_set[0],train_set[1])): 24 img_path=data_path+str(i)+'.jpg'
25 # io.imsave(img_path,img.numpy())
26 f.write(img_path+' '+str(label)+'\n') 27  f.close() 28 else: 29 f = open(root + 'test.txt', 'w') 30 data_path = root + '/test/'
31 if (not os.path.exists(data_path)): 32  os.makedirs(data_path) 33 for i, (img,label) in enumerate(zip(test_set[0],test_set[1])): 34 img_path = data_path+ str(i) + '.jpg'
35 # io.imsave(img_path, img.numpy())
36 f.write(img_path + ' ' + str(label) + '\n') 37  f.close() 38
39 convert_to_img(True)#轉換訓練集
40 convert_to_img(False)#轉換測試集
View Code

此時,轉換後的jpg存儲格式如下:

test和train中的圖片全是未按標簽分類的混合jpg圖片

Step 1.1: 將數據根據txt文件按label分類

在train和test文件夾下分別手動創建10個文件夾,命名從0-9,如新建一個文件夾,文件夾名字為6

代碼實現過程中由於有些需要重複操作,為了便於直接使用 我下面直接按使用步驟全部貼出(可能重複代碼有點多,看懂後你可以直接修改

 1 # 1.1.1 將train文件中的tensor(換為=
 2 fileName = 'rawtrain.txt'
 3 f = open(fileName,'w')  4 lines = f.readlines()  5
 6 for line in lines:  7 f.write(line.replace("tensor(","="))  8  f.close()  9 # 1.1.2 將train文件中的)去掉,不能同時執行tensor(和)的操作,必須順序執行
10 fileName = 'rawtrain.txt'
11 f = open(fileName,'w') 12 lines = f.readlines() 13
14 for line in lines: 15 f.write(line.replace(")", "")) 16  f.close() 17
18 # 1.1.3 將上述的文件名換為'rawtest.txt' 重複執行
19
20 # 1.1.4 按rawtrain.txt文件將圖片移動至對對應標簽的文件夾下
21 fileName = 'rawtrain.txt'
22 f = open(fileName,'r') 23 lines = f.readlines() 24 label = [-1] 25 f = open(fileName,'w') 26
27 for line in lines: 28 splitL = line.split('=') 29 labelnum = int(splitL[1]) 30  label.append(labelnum) 31  f.close() 32 del label[0] 33 # 此時label存儲圖片標簽
34
35 # 讀取圖片並移動
36 root = './raw/train'
37 i = 0 38 lens = len(os.listdir(root)) 39 while(lens > 10): 40 img_path = os.path.join(root, str(i)+'.jpg') 41 img_label = label[i] 42 img_new_path = os.path.join(root, str(img_label), str(i)+'.jpg') 43  shutil.move(img_path, img_new_path) 44 i += 1
45 lens = len(os.listdir(root)) 46
47
48 # 1.1.5 按rawtest.txt文件將圖片移動至對對應標簽的文件夾下
49 fileName = 'rawtest.txt'
50 f = open(fileName,'r') 51 lines = f.readlines() 52 label = [-1] 53 f = open(fileName,'w') 54
55 for line in lines: 56 # f.write(line.replace("tensor(","="))
57 # f.write(line.replace(")", ""))
58 splitL = line.split('=') 59 labelnum = int(splitL[1]) 60  label.append(labelnum) 61  f.close() 62 del label[0] 63 # 此時label存儲圖片標簽
64
65 # 讀取圖片
66 root = './raw/test'
67 i = 0 68 lens = len(os.listdir(root)) 69 while(lens > 10): 70 img_path = os.path.join(root, str(i)+'.jpg') 71 img_label = label[i] 72 img_new_path = os.path.join(root, str(img_label), str(i)+'.jpg') 73  shutil.move(img_path, img_new_path) 74 i += 1
75 lens = len(os.listdir(root))
View Code

 

Step 2: 將raw下的jpg圖片隨機分為10個數據集,每個數據集中的圖片數相同(包括train and test),並且每個數據集下的圖片按標簽分類

分類後的結構如下圖:

代碼實現:

Step 2.1:新建所需要的所有文件夾

 1 root = './newDataSet/'
 2 for labelname in range(10):  3 # domain
 4 domain_path = os.path.join(root, "domain"+str(labelname))  5 # train / test
 6 for use2 in range(2):  7 useName = ''
 8 if use2 == 0:  9 useName = 'train'
10 else: 11 useName = 'test'
12 use_path = os.path.join(domain_path, useName) 13 # label
14 for i in range(10): 15 label_path = os.path.join(use_path, str(i)) 16 if os.path.exists(label_path) != True: 17 try: 18 os.mkdir(label_path) # 創建單層文件夾
19 except Exception as e: 20 os.makedirs(label_path) # 創建多層文件夾
View Code

Step 2.2: 將raw下的數據按一定比例複制到新的文件夾下(我的代碼下不同子數據集的訓練數據是來自train的每個標簽200張-無交叉,test每個標簽50張)

 1 num = 0  2 d_num = 0  3 src_root = './raw/train'
 4 # src_root = './raw/test' # 先執行train 執行結束後再注釋掉train 執行test圖片複制
 5 dst_root = './newDataSet/'
 6 aims = 'train'
 7 # aims = 'test'
 8 for label in os.listdir(src_root): # 0
 9 label_path = os.path.join(src_root, label) 10 for img in os.listdir(label_path): # 1.jpg
11 img_path = os.path.join(label_path, str(img)) 12 img_new_path = os.path.join(dst_root, "domain"+str(d_num), aims, str(label), str(img)) 13  shutil.copyfile(img_path, img_new_path) 14 num += 1
15 if num == 200: 16 # if num == 50: # for test
17 d_num += 1
18 num = 0 19 if d_num == 10: 20 d_num = 0 21 break
View Code

 

Step 3: 將raw下的jpg圖片分為10個數據集,每個數據集中的圖片數相同(包括train and test),並且每個數據集下的圖片僅包含一個標簽的圖片,雖然文件夾結構和第2步相同,但是,如/domain 8/train/1路徑下無圖片,僅/domain 8/train/8下有數字8的圖片,而domain0也僅是Label為0的文件夾下有數字為0的圖片

Step 3.1:新建所需的所有文件夾,代碼參考Step 2.1 只是需要將root名稱換一個

Step 3.2: 將raw下數據按標簽和一定比例複制到新的文件夾下。

 1 num = 0  2 # src_root = './raw/test'
 3 src_root = './raw/train' # 對train文件操作後需要對test文件執行相同的操作
 4 dst_root = './newDatSet1/'
 5 aims = 'train'
 6 # aims = 'test'
 7 for label in os.listdir(src_root): # 0
 8 label_path = os.path.join(src_root, label)  9 for img in os.listdir(label_path): # 1.jpg
10 img_path = os.path.join(label_path, str(img)) 11 img_new_path = os.path.join(dst_root, "domain" + str(label), aims, str(label), str(img)) 12  shutil.copyfile(img_path, img_new_path) 13 num += 1
14 if num == 2000: # train數據為2k,測試數據為500,全部為一個Label的數據
15 # if num == 500:
16 num = 0 17 break
View Code

至此 兩個需要的新的拆分格式的數據集創建完畢。所有代碼已經測試,均正常運行。

 

後續:我的方法好像有點繁瑣了...參考這篇tensorflow的博客好像更簡單。。。

Step 2: 將raw下的jpg圖片隨機分為10個數據集,每個數據集中的圖片數相同(包括train and test),並且每個數據集下的圖片按標簽分類

版权声明:本文为[achived]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/08/20210815125809537l.html