fork download
  1. import math
  2.  
  3. CONV_KERNELS = [
  4. # Filter 0
  5. [
  6. [-0.18, 0.83, 0.09],
  7. [0.57, 0.28, -0.1],
  8. [0.62, 0.26, -0.9],
  9. ],
  10. # Filter 1
  11. [
  12. [0.27, 1.04, 1.0],
  13. [0.16, 0.38, 0.51],
  14. [-2.1, -1.44, -1.54],
  15. ],
  16. # Filter 2
  17. [
  18. [0.39, 0.56, -0.14],
  19. [0.15, 0.7, 0.54],
  20. [-0.09, -0.06, 0.39],
  21. ],
  22. # Filter 3
  23. [
  24. [-0.52, 0.65, 0.72],
  25. [-1.5, -0.15, 0.66],
  26. [-0.87, 0.1, 0.38],
  27. ],
  28. # Filter 4
  29. """Convolutional 2D Layer"""
  30.  
  31. def __init__(self, num_filters, kernel_size, padding='same'):
  32. self.num_filters = num_filters
  33. self.kernel_size = kernel_size
  34. self.padding = padding
  35. self.kernels = None
  36. self.bias = None
  37.  
  38. def set_weights(self, kernels, bias):
  39. """Set weights directly"""
  40. self.kernels = kernels
  41. self.bias = bias
  42.  
  43. def apply_padding(self, image):
  44. """Apply padding to image"""
  45. if self.padding == 'same':
  46. pad = self.kernel_size // 2
  47. height = len(image)
  48. width = len(image[0])
  49.  
  50. # Create padded image
  51. padded = [[0.0 for _ in range(width + 2*pad)] for _ in range(height + 2*pad)]
  52.  
  53. # Copy original image to center
  54. for i in range(height):
  55. for j in range(width):
  56. padded[i + pad][j + pad] = image[i][j]
  57.  
  58. return padded
  59. else:
  60. return image
  61.  
  62. def forward(self, image):
  63. padded_image = self.apply_padding(image)
  64.  
  65. height = len(padded_image)
  66. width = len(padded_image[0])
  67.  
  68. if self.padding == 'same':
  69. out_height = len(image)
  70. out_width = len(image[0])
  71. else:
  72. out_height = height - self.kernel_size + 1
  73. out_width = width - self.kernel_size + 1
  74.  
  75. output = []
  76. for f in range(self.num_filters):
  77. feature_map = []
  78. for i in range(out_height):
  79. row = []
  80. for j in range(out_width):
  81. sum_val = self.bias[f]
  82. for ki in range(self.kernel_size):
  83. for kj in range(self.kernel_size):
  84. sum_val += padded_image[i + ki][j + kj] * self.kernels[f][ki][kj]
  85.  
  86. row.append(max(0, sum_val))
  87. feature_map.append(row)
  88. output.append(feature_map)
  89.  
  90. return output
  91.  
  92. class MaxPooling2D:
  93. def __init__(self, pool_size=2):
  94. self.pool_size = pool_size
  95.  
  96. def forward(self, input_maps):
  97. output = []
  98.  
  99. for feature_map in input_maps:
  100. height = len(feature_map)
  101. width = len(feature_map[0])
  102.  
  103. out_height = height // self.pool_size
  104. out_width = width // self.pool_size
  105.  
  106. pooled = []
  107. for i in range(out_height):
  108. row = []
  109. for j in range(out_width):
  110. max_val = feature_map[i * self.pool_size][j * self.pool_size]
  111. for pi in range(self.pool_size):
  112. for pj in range(self.pool_size):
  113. y = i * self.pool_size + pi
  114. x = j * self.pool_size + pj
  115. if y < height and x < width:
  116. max_val = max(max_val, feature_map[y][x])
  117. row.append(max_val)
  118. pooled.append(row)
  119. output.append(pooled)
  120.  
  121. return output
  122.  
  123. class Dense:
  124. def __init__(self, output_size):
  125. self.output_size = output_size
  126. self.weights = None
  127. self.bias = None
  128.  
  129. def set_weights(self, weights, bias):
  130. self.weights = weights
  131. self.bias = bias
  132.  
  133. def forward(self, input_vector):
  134. output = []
  135.  
  136. for j in range(self.output_size):
  137. sum_val = self.bias[j]
  138. for i in range(len(input_vector)):
  139. sum_val += input_vector[i] * self.weights[i][j]
  140. output.append(sum_val)
  141.  
  142. return output
  143.  
  144. class SimpleCNN:
  145. def __init__(self):
  146. self.conv = Conv2D(num_filters=5, kernel_size=3, padding='same')
  147. self.maxpool = MaxPooling2D(pool_size=2)
  148. self.dense = Dense(output_size=10)
  149.  
  150. self.conv.set_weights(CONV_KERNELS, CONV_BIAS)
  151. self.dense.set_weights(DENSE_WEIGHTS, DENSE_BIAS)
  152.  
  153. def flatten(self, feature_maps):
  154. flat = []
  155. h = len(feature_maps[0])
  156. w = len(feature_maps[0][0])
  157. for i in range(h):
  158. for j in range(w):
  159. for f in range(len(feature_maps)):
  160. flat.append(feature_maps[f][i][j])
  161. return flat
  162.  
  163. def softmax(self, logits):
  164. max_val = max(logits)
  165. exp_vals = []
  166. for val in logits:
  167. exp_vals.append(math.exp(val - max_val))
  168.  
  169. sum_exp = sum(exp_vals)
  170. probabilities = []
  171. for exp_val in exp_vals:
  172. probabilities.append(exp_val / sum_exp)
  173.  
  174. return probabilities
  175.  
  176. def forward(self, image):
  177. conv_output = self.conv.forward(image)
  178. pool_output = self.maxpool.forward(conv_output)
  179. flat = self.flatten(pool_output)
  180. logits = self.dense.forward(flat)
  181. probabilities = self.softmax(logits)
  182.  
  183. return probabilities
  184.  
  185. def predict(self, image):
  186. probabilities = self.forward(image)
  187.  
  188. max_prob = probabilities[0]
  189. predicted_class = 0
  190.  
  191. for i in range(1, len(probabilities)):
  192. if probabilities[i] > max_prob:
  193. max_prob = probabilities[i]
  194. predicted_class = i
  195.  
  196. return predicted_class, max_prob, probabilities
  197.  
  198. def get_image_from_user():
  199. image = []
  200.  
  201. for _ in range(40):
  202. while True:
  203. line = input().strip()
  204.  
  205. values = line.split()
  206.  
  207. if len(values) != 40:
  208. continue
  209.  
  210. valid = True
  211. row = []
  212. for val in values:
  213. if val not in ['0', '1']:
  214. valid = False
  215. break
  216. row.append(float(val))
  217.  
  218. if valid:
  219. image.append(row)
  220. break
  221.  
  222. return image
  223.  
  224. def resize_image_bilinear(image, new_size):
  225. old_size = len(image)
  226. scale = (old_size - 1) / (new_size - 1) if new_size > 1 else 0
  227.  
  228. resized = []
  229. for i in range(new_size):
  230. row = []
  231. for j in range(new_size):
  232. y = i * scale
  233. x = j * scale
  234.  
  235. y0 = int(y)
  236. x0 = int(x)
  237. y1 = min(y0 + 1, old_size - 1)
  238. x1 = min(x0 + 1, old_size - 1)
  239.  
  240. dy = y - y0
  241. dx = x - x0
  242.  
  243. val = (1 - dx) * (1 - dy) * image[y0][x0] + \
  244. dx * (1 - dy) * image[y0][x1] + \
  245. (1 - dx) * dy * image[y1][x0] + \
  246. dx * dy * image[y1][x1]
  247.  
  248. row.append(1.0 if val > 0.5 else 0.0)
  249. resized.append(row)
  250.  
  251. return resized
  252.  
  253. def main():
  254. model = SimpleCNN()
  255. image = get_image_from_user()
  256. image = resize_image_bilinear(image, 28)
  257. predicted_class, _, _ = model.predict(image)
  258.  
  259. print(predicted_class)
  260.  
  261. if __name__ == "__main__":
  262. main()
  263.  
Success #stdin #stdout 0.07s 14244KB
stdin
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
stdout
5