Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.29 MB, 34 trang )
<span class="text_page_counter">Trang 1</span><div class="page_container" data-page="1">
TRƯỜNG ĐẠI HỌC
SƯ PHẠM KỸ THUẬT THÀNH PHỐ HỒ CHÍ MINH ----
----HCMC University of Technology and Education KHOA ĐÀO TẠO CHẤT LƯỢNG CAO
NGÀNH CÔNG NGHỆ THÔNG TIN BÁO CÁO ĐỒ ÁN
HỌC MÁY
GVHD: Trần Tiến Đức Nhóm sinh viên thực hiện:
</div><span class="text_page_counter">Trang 2</span><div class="page_container" data-page="2">
ĐIỂM SỐ
NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN:
(Kí và ghi rõ họ tên)
</div><span class="text_page_counter">Trang 3</span><div class="page_container" data-page="3">LỜI CẢM ƠN
Để hoàn thành tốt đề tài và bài báo cáo này, chúng em xin gửi lời cảm ơn chân thành đến giảng viên Trần Tiến Đức, các quý thầy cơ trong khoa Đào tạo Chất Lượng Cao nói chung và ngành Cơng Nghệ Thơng Tin nói riêng đã tận tình truyền đạt những kiến thức cần thiết giúp chúng em có nền tảng để làm nên đề tài này, đã tạo điều kiện để chúng em có thể tìm hiểu và thực hiện tốt đề tài. Cùng với đó, chúng em xin được gửi cảm ơn đến các bạn cùng khóa đã cung cấp nhiều thơng tin và kiến thức hữu ích giúp chúng em có thể hồn thiện hơn đề tài của mình.
Đề tài và bài báo cáo được chúng em thực hiện trong khoảng thời gian ngắn, với những kiến thức còn hạn chế cùng nhiều hạn chế khác về mặt kĩ thuật và kinh nghiệm trong việc thực hiện một dự án phần mềm. Do đó, trong q trình làm nên đề tài có những thiếu sót là điều khơng thể tránh khỏi nên chúng em rất mong nhận được những ý kiến đóng góp q báu của các q thầy cơ để kiến thức của chúng em được hoàn thiện hơn và chúng em có thể làm tốt hơn nữa trong những lần sau. Chúng em xin chân thành cảm ơn.
Cuối lời, chúng em kính chúc quý thầy, quý cô luôn dồi dào sức khỏe và thành công hơn nữa trong sự nghiệp trồng người. Một lần nữa chúng em xin chân thành cảm ơn.
TP.HCM, ngày tháng 5 năm 2023
</div><span class="text_page_counter">Trang 5</span><div class="page_container" data-page="5">Mục lục
Chương 1: Tổng quan chương trình...1
1.1. Giới thiệu về chương trình:...1
1.2. Mục đích, tính năng:...1
1.2.1. Mục đích:...1
1.2.2. Tính năng:...1
Chương2. Thiết kế trang web và code nhận dạng...2
2.1. Thiết kế giao diện:...2
2.1.1. Giao diện chính:...2
2.1.2 Giao diện trang IRIS EDA...2
2.1.3 Giao diện trang Dự báo giá nhà California...4
2.1.4 Giao diện trang Phát hiện gương mặt...4
2.1.5 Giao diện trang Nhận dạng chữ số viết tay...5
2.1.6 Giao diện trang Nhận dạng các loài bướm...5
2.1.7 Giao diện trang Nhận dạng khuôn mặt...6
</div><span class="text_page_counter">Trang 6</span><div class="page_container" data-page="6">Chương 1: Tổng quan chương trình
1.1. Giới thiệu về chương trình:
Các chế độ: Trang web có 6 chức năng nhận dạng chữ số viết tay, dự đoán giá nhà ở California, phát hiện khuôn mặt và nhận diện khuôn mặt, nhận dạng lồi bướm, phân tích lồi hoa Iris.
Cách dùng: Ở trang chủ người dùng sẽ thấy được thông tin của trang web. Phần danh mục bên trái sẽ là các chức năng chính của trang web. Khi chọn vào Nhận dạng chữ số viết tay thì sẽ chuyển sang trang nhận dạng chữ viết tay, bên trong sẽ có một nút tạo ảnh và nhận dạng. Khi chọn vào nút này thì trang web sẽ tạo một bảng các chữ số viết tay và tiến hành nhận dạng các chữ số đó. Khi chọn vào Dự báo giá nhà California thì trang web thì cung cấp các thông tin liên quan đến giá nhà ở California. Khi chọn vào Nhận dạng loài bướm, chúng ta sẽ tiến hành upload một ảnh bướm bất kì và chọn vào nút nhận dạng. Trang web sẽ trả về tên của lồi bướm có trong ảnh. Khi chọn và Phân tích lồi hoa Iris, trang web sẽ hiển thị tất cả thơng tin về lồi hoa này. Khi chọn và Phát hiện gương mặt, trang web sẽ thực hiện mở camera và tiến hành phát hiện gương mặt ngồi trước camera. Khi chọn vào Nhận dạng khuôn mặt, trang web sẽ mở camera và tiến hành nhận dạng người ngồi trước camera và trả về thơng tin là tên của người đó (hình ảnh của người này đã được tranning từ trước).
1.2. Mục đích, tính năng: 1.2.1. Mục đích:
Ứng dụng các kiến thức đã học từ môn Machine Learning.
Cung cấp các chức năng hữu ích và thơng minh để đáp ứng các như cầu
</div><span class="text_page_counter">Trang 7</span><div class="page_container" data-page="7">Chương2. Thiết kế trang web và code nhận dạng
2.1. Thiết kế giao diện: 2.1.1. Giao diện chính:
Trang chủ:
2.1.2 Giao diện trang IRIS EDA
</div><span class="text_page_counter">Trang 9</span><div class="page_container" data-page="9">2.1.3 Giao diện trang Dự báo giá nhà California
2.1.4 Giao diện trang Phát hiện gương mặt
</div><span class="text_page_counter">Trang 10</span><div class="page_container" data-page="10">2.1.5 Giao diện trang Nhận dạng chữ số viết tay
2.1.6 Giao diện trang Nhận dạng các loài bướm
5
</div><span class="text_page_counter">Trang 11</span><div class="page_container" data-page="11">2.1.7 Giao diện trang Nhận dạng khn mặt
2.2. Code chương trình:
2.2.1 Thư viện và framework sử dụng chính:
Để thực hiện được bài này chúng em đã dùng một số thư viện và framework của python để có thể hồn thành được bài tập như là streamlit, pandas, numpy, os, matplotlib, seaborn, PIL, joblib, opencv, tensorflow, tempfile.
</div><span class="text_page_counter">Trang 12</span><div class="page_container" data-page="12">Hiển thị toàn bộ khung dữ liệu
</div><span class="text_page_counter">Trang 13</span><div class="page_container" data-page="13">L=len( )s :ifL<14
s=' '*(14-L) +s returns
forest_reg =joblib.load("pages model forest_reg_model.pkl"\\ \\ )
column_names=['longitude' 'latitude' 'housing_median_age' 'total_rooms', , , , 'total_bedrooms' 'population' 'households' 'median_income', , , , 'rooms_per_household' 'population_per_household', , 'bedrooms_per_room' 'ocean_proximity_1', , 'ocean_proximity_2' 'ocean_proximity_3', , 'ocean_proximity_4' 'ocean_proximity_5', ] st.subheader('Dự báo giá nhà California')
x_test =pd.read_csv('pages model x_test.csv'\\ \\ , header =None, names column_names= )
y_test =pd.read_csv('pages model y_test.csv'\\ \\ , header =None) y_test y_test = .to_numpy()
N =len(x_test) st.dataframe(x_test)
get_5_rows =st.button('Lấy 5 hàng ngẫu nhiên và dự báo') if get_5_rows:
index =np random. .randint(0,N-1 5, ) some_data =x_test.iloc[index]
st.markdown result unsafe_allow_html=True( , ) some_data =some_data.to_numpy()
y_pred =forest_reg.predict(some_data) result ='y_predict:' +' '
</div><span class="text_page_counter">Trang 14</span><div class="page_container" data-page="14">my_format(x): Hàm này nhận một số x làm đầu vào và định dạng nó thành một chuỗi với dấu phẩy ngăn cách hàng nghìn. Nó sử dụng chuỗi định dạng "{:,.0f}" để làm điều này. Hàm cũng kiểm tra độ dài của chuỗi đã định dạng và thêm các không gian không ngắt ( ) trước số để đảm bảo một độ rộng 14 ký tự nhất quán. forest_reg = joblib.load("pages\\model\\forest_reg_model.pkl"): Dòng này tải một mơ hình học máy từ tệp "forest_reg_model.pkl" bằng cách sử dụng hàm
joblib.load(). Mơ hình đã tải được gán cho biến forest_reg.
column_names: Danh sách này chứa tên cột cho các đặc trưng được sử dụng trong mơ hình.
st.subheader('Dự báo giá nhà California'): Dịng này hiển thị một tiêu đề phụ với nội dung "Dự báo giá nhà California" bằng cách sử dụng hàm st.subheader() từ thư viện Streamlit.
x_test = pd.read_csv('pages\\model\\x_test.csv', header=None,
names=column_names): Dòng này đọc dữ liệu kiểm tra từ tệp "x_test.csv" vào một DataFrame của Pandas có tên là x_test. Đối số header=None chỉ định rằng tệp CSV khơng có hàng tiêu đề và đối số names=column_names gán các tên cột cho DataFrame.
y_test = pd.read_csv('pages\\model\\y_test.csv', header=None): Dòng này đọc giá trị mục tiêu kiểm tra từ tệp "y_test.csv" vào một DataFrame của Pandas có tên là y_test. Nó giả định rằng các giá trị mục tiêu được lưu trữ trong một cột duy nhất. y_test = y_test.to_numpy(): Dòng này chuyển đổi DataFrame y_test thành một mảng NumPy.
N = len(x_test): Dịng này tính số hàng trong DataFrame x_test và gán cho biến N. st.dataframe(x_test): Dòng này hiển thị DataFrame x_test bằng cách sử dụng hàm st.dataframe() từ Streamlit.
get_5_rows = st.button('Lấy 5 hàng ngẫu nhiên và dự báo'): Dòng này tạo một nút có nhãn "Lấy 5 hàng ngẫu nhiên và dự báo" bằng cách sử dụng hàm st.button(). Khi nút này được nhấp, nó kích hoạt đoạn mã tiếp theo.
Trong khối if get_5_rows:, đoạn mã chọn ngẫu nhiên 5 chỉ số từ 0 đến N-1 và gán chúng cho biến index.
some_data = x_test.iloc[index]: Dòng này chọn các hàng tương ứng với các chỉ số trong index từ DataFrame x_test và gán kết quả là một DataFrame con có tên là some_data.
9
</div><span class="text_page_counter">Trang 15</span><div class="page_container" data-page="15">st.dataframe(some_data): Dòng này hiển thị DataFrame some_data bằng cách sử dụng hàm st.dataframe().
Mã sau đó tạo một chuỗi result để hiển thị các giá trị thực tế (y_test) và giá trị dự đoán (y_pred) cho các hàng đã chọn. Nó định dạng các giá trị bằng cách sử dụng hàm my_format() và thêm không gian không ngắt để giữ cho các giá trị được căn chỉnh nhất quán.
2.2.4 Phát hiện gương mặt FRAME_WINDOW =st.image([]) deviceId =0
cap =cv.VideoCapture deviceId( ) if 'stop' not in st.session_state: st.session_state.stop =False stop =False
press =st.button('Stop') if press:
ifst.session_state.stop ==False: st.session_state.stop =True cap.release()
else:
st.session_state.stop =False
print('Trang thai nhan Stop', st.session_state.stop) if 'frame_stop' not in st.session_state:
frame_stop =cv.imread('pages image stop.jpg'\\ \\ ) st.session_state.frame_stop =frame_stop print('Đã load stop.jpg')
if st.session_state.stop == True:
FRAME_WINDOW.image( .stsession_state.frame_stop, channels='BGR') def visualize(input faces fps thickness, , , =2):
iffaces[1] is not None:
foridx face, inenumerate(faces[1]):
# print('Face {}, top-left coordinates: ({:.0f}, {:.0f}), box width: {:.0f}, box height {:.0f}, score: {:.2f}'.format(idx, face[0], face[1], face[2], face[3], face[-1]))
</div><span class="text_page_counter">Trang 16</span><div class="page_container" data-page="16">coords =face[: ].astype( .-1 npint32)
cv.rectangle(input coords[0, ( ], coords[1]), (coords[0]+coords[2], coords[1]+coords[3]), ( , 0 255 0, ), thickness)
cv.circle(input coords[4, ( ], coords[5]), , (2 255 0 0, , ), thickness) cv.circle(input coords[6, ( ], coords[7]), , ( , , 2 0 0 255), thickness) cv.circle(input coords[8, ( ], coords[9]), , ( , 2 0 255 0, ), thickness) cv.circle(input coords[10, ( ], coords[11]), , (2 255 0 255, , ), thickness) cv.circle(input coords[12, ( ], coords[13]), , ( , 2 0 255 255, ), thickness) cv.putText(input, 'FPS: {:.2f}'.format(fps), ( , ), 1 16
frameWidth =int(cap.get( .cvCAP_PROP_FRAME_WIDTH)) frameHeight =int(cap.get( .cvCAP_PROP_FRAME_HEIGHT)) detector.setInputSize([frameWidth frameHeight, ])
# Draw results on the input image visualize(frame faces tm.getFPS()), , # Visualize results
FRAME_WINDOW.image(frame channels='BGR', ) cv.destroyAllWindows()
11
</div><span class="text_page_counter">Trang 17</span><div class="page_container" data-page="17">FRAME_WINDOW = st.image([]): Đoạn mã này tạo một khung hình để hiển thị các khung hình từ luồng video hoặc hình ảnh.
deviceId = 0: Biến này xác định ID của thiết bị đầu vào, ví dụ như webcam. cap = cv.VideoCapture(deviceId): Đoạn mã này tạo một đối tượng VideoCapture từ OpenCV để nhận luồng video từ thiết bị đầu vào có ID là deviceId.
st.session_state.stop: Trạng thái stop được lưu trữ trong st.session_state. Nếu nút 'stop' khơng có trong st.session_state, giá trị ban đầu của stop được đặt là False. press = st.button('Stop'): Tạo một nút với nhãn 'Stop' bằng cách sử dụng st.button(). if press: ...: Nếu nút 'Stop' được nhấp, dòng mã này kiểm tra giá trị của
st.session_state.stop để quyết định xem liệu việc dừng lại (stop) là cần thiết hay không. Nếu st.session_state.stop là False, nghĩa là đang chạy, thì giá trị của st.session_state.stop được đặt thành True và luồng video được giải phóng
(cap.release()). Ngược lại, nếu st.session_state.stop là True, nghĩa là đang dừng, thì giá trị của st.session_state.stop được đặt thành False, và việc chạy luồng video được tiếp tục.
if st.session_state.stop == True: ...: Nếu st.session_state.stop là True, nghĩa là đang dừng, hình ảnh trong tệp 'stop.jpg' được hiển thị trong khung hình
FRAME_WINDOW bằng cách sử dụng FRAME_WINDOW.image().
visualize(input, faces, fps, thickness=2): ...: Hàm visualize() nhận các đối số input (hình ảnh), faces (các khn mặt được phát hiện), fps (số khung hình/giây), và thickness (độ dày của đường viền) để vẽ các hình chữ nhật xung quanh các khuôn mặt và các điểm đặc trưng trên hình ảnh.
detector = cv.FaceDetectorYN.create(...): ...: Đoạn mã này tạo một đối tượng nhận diện khuôn mặt (detector) từ một mơ hình đã được đào tạo và cấu hình của nó. while True: ...: Vịng lặp vơ hạn này sẽ tiếp tục chạy cho đến khi có một lỗi trong việc nhận các khung hình từ luồng video.
hasFrame, frame = cap.read(): Dịng này đọc một khung hình từ luồng video và gán nó cho biến frame, cùng với một biến boolean hasFrame để xác định xem việc đọc khung hình thành cơng hay khơng.
</div><span class="text_page_counter">Trang 18</span><div class="page_container" data-page="18">frame = cv.resize(frame, (frameWidth, frameHeight)): Hình ảnh được đọc từ luồng video có thể có kích thước khác với kích thước khung hình mong muốn, vì vậy hình ảnh được điều chỉnh kích thước để phù hợp với khung hình mong muốn.
faces = detector.detect(frame): Đoạn mã này sử dụng đối tượng detector để phát hiện các khuôn mặt trong frame. Kết quả là một tuple faces chứa các thông tin về khuôn mặt đã được phát hiện.
visualize(frame, faces, tm.getFPS()): Dòng này gọi hàm visualize() để vẽ các hình chữ nhật và điểm đặc trưng trên hình ảnh frame dựa trên thơng tin khn mặt đã phát hiện trong faces.
FRAME_WINDOW.image(frame, channels='BGR'): Cuối cùng, hình ảnh được hiển thị trong khung hình FRAME_WINDOW bằng cách sử dụng
2.2.5 Nhận dạng chữ số viết tay
model_architecture ="pages model digit_config.json"\\ \\ model_weights ="pages model digit_weight.h5"\\ \\
model model_from_json(= open(model_architecture).read()) model.load_weights(model_weights)
optim SGD()=
model.compile(loss="categorical_crossentropy", optimizer optim= , metrics=["accuracy"])
mnist =keras datasets mnist. .
(X_train, Y_train), (X_test Y_test, ) =mnist.load_data() X_test_image X_test =
RESHAPED =784
X_test X_test = .reshape(10000, RESHAPED) X_test X_test = .astype('float32')
X_test /= 255
def predict_digit(X_test_sample):
prediction =model.predict(X_test_sample) returnprediction
def main():
st.set_page_config(page_title='Nhận Dạng Chữ Số Viết Tay') st.title('Nhận Dạng Chữ Số Viết Tay')
st.text('Tạo ảnh để xem kết quả nhận dạng')
ifst.button('Tạo ảnh và Nhận dạng'):
13
</div><span class="text_page_counter">Trang 19</span><div class="page_container" data-page="19">index =np random. .randint(0 9999 150, , )
digit_random =np.zeros((10 28* , 15 28* ), dtype=np.uint8) X_test_sample =np.zeros((150 784, ), dtype=np.float32)
prediction =model.predict(X_test_sample[].reshape( , ))1-1 ket_qua =np.argmax(prediction)
s=s+str(ket_qua) +' ' (if i+1) %15== :0 s=s+'\n'
cv2.imwrite('pages image digit_random.jpg'\\ \\ , digit_random) image =Image.open('pages image digit_random.jpg'\\ \\ )
st.image image caption='Hình ảnh tạo ra'( , , use_column_width=True) st.write('Kết quả nhận dạng: ')
st.write(s)
if __name__ == "__main__": main()
model_architecture = "pages\\model\\digit_config.json": Đường dẫn đến tệp JSON chứa kiến trúc (architecture) của mơ hình.
model_weights = "pages\\model\\digit_weight.h5": Đường dẫn đến tệp trọng số (weights) của mơ hình.
model = model_from_json(open(model_architecture).read()): Tạo một đối tượng mơ hình từ kiến trúc được đọc từ tệp JSON.
model.load_weights(model_weights): Tải trọng số của mơ hình từ tệp trọng số. optim = SGD(): Tạo một bộ tối ưu hóa SGD (Stochastic Gradient Descent). model.compile(loss="categorical_crossentropy", optimizer=optim,
metrics=["accuracy"]): Biên dịch mơ hình với hàm mất mát (loss function) là categorical cross-entropy, bộ tối ưu hóa là SGD và độ đo là accuracy.
</div><span class="text_page_counter">Trang 20</span><div class="page_container" data-page="20">(X_train, Y_train), (X_test, Y_test) = mnist.load_data(): Phân chia tập dữ liệu MNIST thành tập huấn luyện và tập kiểm tra.
X_test_image = X_test: Sao chép tập dữ liệu kiểm tra vào biến X_test_image để sử dụng về sau.
RESHAPED = 784: Định dạng lại kích thước các hình ảnh từ ma trận 2D thành vector 1D có kích thước 784 (28x28).
X_test = X_test.reshape(10000, RESHAPED): Định dạng lại tập dữ liệu kiểm tra thành vector 1D với kích thước là 784.
X_test = X_test.astype('float32'): Chuyển đổi kiểu dữ liệu của X_test thành float32. X_test /= 255: Chuẩn hóa dữ liệu trong X_test bằng cách chia cho 255 để đưa giá trị về khoảng từ 0 đến 1.
predict_digit(X_test_sample): Hàm predict_digit() được định nghĩa để dự đoán chữ số từ mẫu X_test_sample bằng cách sử dụng mơ hình đã được tải.
def main(): ...: Hàm main() được định nghĩa để chạy ứng dụng nhận dạng chữ số viết tay.
`st.set_page_config(page_title='Nhận Dạng Chữ Số Viết Tay')`: Đặt cấu hình trang cho ứng dụng.
st.title('Nhận Dạng Chữ Số Viết Tay'): Hiển thị tiêu đề trang.
st.text('Tạo ảnh để xem kết quả nhận dạng'): Hiển thị văn bản hướng dẫn.
if st.button('Tạo ảnh và Nhận dạng'): ...: Kiểm tra xem nút "Tạo ảnh và Nhận dạng" có được nhấn hay không.
index = np.random.randint(0, 9999, 150): Tạo một mảng gồm 150 giá trị ngẫu nhiên trong khoảng từ 0 đến 9999.
digit_random = np.zeros((10*28, 15*28), dtype=np.uint8): Tạo một mảng numpy 2D có kích thước (280, 420) và kiểu dữ liệu uint8 để lưu trữ hình ảnh được tạo. X_test_sample = np.zeros((150,784), dtype=np.float32): Tạo một mảng numpy 2D có kích thước (150, 784) và kiểu dữ liệu float32 để lưu trữ các mẫu dữ liệu kiểm tra.
15
</div>