jiehou commited on
Commit
ee13d2c
·
1 Parent(s): 668444e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +146 -0
app.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## CSCI4750/5750: homework03 submission
2
+ ## load the dataset
3
+ def hw03_derive_MNIST_train_test_data():
4
+ from sklearn.datasets import fetch_openml
5
+ import numpy as np
6
+ mnist = fetch_openml('mnist_784', version=1, as_frame=False)
7
+ X, y = mnist["data"], mnist["target"]
8
+ X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]
9
+ y_train = y_train.astype(np.int) # convert to int
10
+ y_test = y_test.astype(np.int) # convert to int
11
+ return X_train, X_test, y_train, y_test
12
+
13
+ X_train, X_test, y_train, y_test = hw03_derive_MNIST_train_test_data()
14
+ print("X_train.shape: ", X_train.shape)
15
+ print("X_test.shape: ", X_test.shape)
16
+ print("y_train.shape: ", y_train.shape)
17
+ print("y_test.shape: ", y_test.shape)
18
+
19
+ train_features = X_train
20
+ train_labels = y_train
21
+ test_feature = X_test[0]
22
+ K = 3
23
+ print("train_features: ",train_features.shape)
24
+ print("train_labels: ",train_labels.shape)
25
+ print("test_feature: ",test_feature.shape)
26
+
27
+ # Practice 5: deploy our KNN classifier to web application, with multiple outputs
28
+
29
+ import scipy
30
+ import gradio as gr
31
+ import numpy as np
32
+ import cv2
33
+ import os
34
+
35
+ def get_sample_images(num_images):
36
+ sample_images = []
37
+ for i in range(num_images):
38
+ train_feature = X_train[i]
39
+ train_feature_2d =train_feature.reshape(28,28)
40
+
41
+ # Make it unsigned integers:
42
+ data = train_feature_2d.astype(np.uint8)
43
+
44
+ outdir = "images_folder"
45
+ img_path = os.path.join(outdir, 'local_%05d.png' % (i,))
46
+ if not os.path.exists(outdir):
47
+ os.mkdir(outdir)
48
+ cv2.imwrite(img_path, data)
49
+
50
+ sample_images.append([img_path,int(np.random.choice([7,9,11,13]))]) # ["image path", "K"]
51
+ return sample_images
52
+
53
+ # EXTRA: adapted from https://github.com/ageron/handson-ml2/blob/master/03_classification.ipynb
54
+ def plot_digits(instances, images_per_row=3):
55
+ import matplotlib.pyplot as plt
56
+ import matplotlib as mpl
57
+ size = 28
58
+ images_per_row = min(len(instances), images_per_row)
59
+ # This is equivalent to n_rows = ceil(len(instances) / images_per_row):
60
+ n_rows = (len(instances) - 1) // images_per_row + 1
61
+
62
+ n = len(instances)
63
+
64
+ fig = plt.figure()
65
+ for i in range(len(instances)):
66
+ # Debug, plot figure
67
+ fig.add_subplot(n_rows, images_per_row, i + 1)
68
+ #print(instances[i])
69
+ plt.imshow(instances[i].reshape(size,size), cmap = mpl.cm.binary)
70
+ plt.axis("off")
71
+ plt.title("Neighbor "+str(i+1))
72
+ fig.tight_layout()
73
+
74
+ plt.savefig('results.png', dpi=300)
75
+ return 'results.png'
76
+
77
+
78
+ ## machine learning classifier
79
+ def KNN_predict(train_features, train_labels, test_feature, K):
80
+ label_record = []
81
+ for i in range(len(train_features)):
82
+ train_point_feature = train_features[i]
83
+ test_point_feature = test_feature
84
+ ### (1) calculate distance between test feature and each of training data points
85
+
86
+ # get distance for data point i
87
+ dis = scipy.spatial.distance.euclidean(train_point_feature, test_point_feature)
88
+
89
+ # collect lable for datapoint i
90
+ y = train_labels[i]
91
+ label_record.append((dis, y, train_point_feature))
92
+
93
+ # sort data points by distance
94
+ from operator import itemgetter
95
+ sorted_labels = sorted(label_record,key=itemgetter(0))
96
+ # get major class from top K neighbors
97
+ major_class = []
98
+ neighbor_imgs = []
99
+ for k in range(K):
100
+ major_class.append(sorted_labels[k][1])
101
+
102
+ # at most 15 neighbors for visualization
103
+ if k <15:
104
+ neighbor_feature = sorted_labels[k][2]
105
+ neighbor_imgs.append(neighbor_feature)
106
+
107
+ ### get final prediction
108
+ final_prediction = scipy.stats.mode(major_class).mode[0]
109
+
110
+ ### get neighbor images and save to local
111
+ neighbor_imgs =np.array(neighbor_imgs)
112
+ image_path = plot_digits(neighbor_imgs, images_per_row=3)
113
+
114
+ return final_prediction, image_path
115
+
116
+ ### main function for gradio to call to classify image
117
+ def call_our_KNN(test_image, K=7):
118
+ test_image_flatten = test_image.reshape((-1, 28*28))
119
+ y_pred_each, image_path = KNN_predict(train_features, train_labels, test_image_flatten, K)
120
+ return y_pred_each, image_path
121
+
122
+
123
+ ### generate several example cases
124
+ sample_images = get_sample_images(10)
125
+
126
+ ### configure inputs/outputs
127
+ set_image = gr.inputs.Image(shape=(28, 28), image_mode='L')
128
+ set_K = gr.inputs.Slider(0, 100, default=7)
129
+
130
+ set_label = gr.outputs.Textbox(label="Predicted Digit")
131
+ set_out_images = gr.outputs.Image(label="Closest Neighbors")
132
+
133
+
134
+ ### configure gradio, detailed can be found at https://www.gradio.app/docs/#i_slider
135
+ interface = gr.Interface(fn=call_our_KNN,
136
+ inputs=[set_image, set_K],
137
+ outputs=[set_label,set_out_images],
138
+ examples_per_page = 2,
139
+ examples = sample_images,
140
+ title="CSCI4750: Digit classification using KNN algorithm",
141
+ description= "Click examples below for a quick demo",
142
+ theme = 'huggingface',
143
+ layout = 'vertical',
144
+ live=True
145
+ )
146
+ interface.launch(debug=True)