سلام
شما کلا باید دوتا آرایه داشته باشید یکی داده و یکی هم لیبل ها . (برای تست هم به همین صورت هست )
کاری که میکنید تصاویر رو از ورودی میخونید بعد هر تصویر رو به یک بردار تبدیل میکنید . میتونید از reshape استفاده کنید میتونید از flatten هم استفاده کنید. اگه همه تصاویر رو بخونید در داخل یک آرایه بزرگ برای اینکه سربار زیادی ایجاد نشه میتونید از ravel() بجای flatten هم استفاده کنید.
مثلا کد زیر تصاویر یه پوشه رو میخونه تبدیل به بردار میکنه و بعد در یک آرایه دو بعدی به همین منظور ذخیره میکنه . اندازه تصاویر مثلا ۲۸ در ۲۸ هست (سایز ام نیست ) و تعداد ترینینگ ست شما هم مثلا ۱۰ .
import numpy as np
import matplotlib.pyplot as plt
try:
from scipy import misc
except ImportError:
!pip install scipy
from scipy import misc
training_size = 10
img_size = 28*28
training_data = np.empty(shape=(training_size, img_size))
import glob
i = 0
for filename in glob.glob('/home/hossein/Pictures/*.jpg'):
image = misc.imread(filename)
#اینجا تصویر رو در قالب یه وکتور یه بعدی در میاریم و بعد ذخیره اش میکنیم
training_data[i] = image.reshape(-1)
i+=1
print(training_data[0].shape)
بعد شما لیبل ها رو میخونید اما باید بجای یه وکتور با سایز ۱۰ (که شماره هر کلاس در یک خونه ذخیره شده )یه آرایه دو بعدی به سایز [training_set_size, number_of_classes] و بعد ببینید شماره کدوم کلاسه و اندیس متناظر با اون ۱ و بقیه رو صفر کنید .
یه شیوه ساده برای خوندن لیبل ها میتونه اینطور باشه
مثلا فایل لیبل من فرمتش به این شکل هست :
img1.png 1
img2.png 2
img3.png 3
img4.png 4
img5.png 5
و اینطور میشه عمل کرد :
In [2]: labels = []
...: with open("C:/Users/Hossein/Documents/labels.txt") as f:
...: for line in f:
...: if len(line.strip()) !=0 :
...: labels.append(line.strip().split(' ')[1])
اون if هم برای اینه که اگه چندتا خط خالی باشه مارو دچار خطا نکنه . خروجی هم بصورت لیست هست. اگه مستقیما میخواییم تو یه آرایه numpy نتایج رو داشته باشیم میشه اینطور عمل کرد (اون 5 تعداد ایتم های ماست. یعنی چندتا عکس داریم!):
In [3]: labels = np.empty(5,dtype=np.uint8)
...: i = 0
...: with open("C:/Users/Hossein/Documents/labels.txt") as f:
...: for line in f:
...: if len(line.strip()) !=0 :
...: labels[i] = line.strip().split(' ')[1]
...: i+=1
...:
...:
In [4]: labels
Out[4]: array([1, 2, 3, 4, 5], dtype=uint8)
میتونید این کار رو بصورت یکدفعه و یکجا انجام بدید به اینصورت که اول همه لیبلها رو در یک وکتور بخونید بعد با استفاده از دستور زیر ماتریس مورد نظرتون رو بدست بیارید :
import numpy as np
np.eye(Tedade_classha)[Vector_labelha]
مثلا اگر 10 کلاس دارید و تعداد ایتم ها هم 10 تاس یعنی 10 تا عکس داریم که لیبلهاشون به ترتیب بصورت زیر باشه دستور به شکل زیر در میاد
np.eye(10)[[2, 4, 1,0,3,5,9,8,7,6]]
که خروجیش میشه مثل شکل زیر :
Out[5]:
array([[ 0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.]])
اگه ورودی 3 تا بود مثلا میشه این مثلا
In [6]: np.eye(10)[[2, 4, 1]]
Out[6]:
array([[ 0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.]])
یه روش خیلی ساده تر هم اخیرا فهمیدم که از این ساده تره و اونم استفاده از تابع get_dummies مربوط به pandas هست. همون مثال قبل رو میشه براحتی بصورت زیر هم حساب کرد:
In [7]: import pandas as pd
In [8]: pd.get_dummies(a)
Out[8]:
0 1 2 3 4 5 6 7 8 9
0 0 0 1 0 0 0 0 0 0 0
1 0 0 0 0 1 0 0 0 0 0
2 0 1 0 0 0 0 0 0 0 0
3 1 0 0 0 0 0 0 0 0 0
4 0 0 0 1 0 0 0 0 0 0
5 0 0 0 0 0 1 0 0 0 0
6 0 0 0 0 0 0 0 0 0 1
7 0 0 0 0 0 0 0 0 1 0
8 0 0 0 0 0 0 0 1 0 0
9 0 0 0 0 0 0 1 0 0 0
دیگه کار خاصی ندارید و میتونید از بقیه کد ها استفاده کنید.
البته تنسورفلو از ورژن .07 انگار تابع one_hot رو قرار داده که میتونید از اون هم استفاده کنید و نیازی به این دستور بالا نداشته باشید . اینجا رو بخونید
برای تنسورفلو هم میتونید از تابع one_hot استفاده کنید که توضیح دادم . نحوه استفاده اش هم بصورت زیر هست :
tf.one_hot(a,10)
که اولی یه آرایه حاوی لیبلهای شماست و دومین پارامتر یا همون پارامتر depth شما تعداد کلاسهای شما رو مشخص میکنه. مثل بالا رو در پایین زدم تا مشخص باشه :
In [9]: a = [2, 4, 1,0,3,5,9,8,7,6]
In [10]: b = tf.one_hot(a,10)
In [11]: sess = tf.Session()
In [12]: sess.run(b)
Out[12]:
array([[ 0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.]], dtype=float32)