My solution
import numpy as np
def layer_1_z(x, w1, b1):
return 1 / w1 * x + b1
def layer_2(x, w1, b1, w2, b2):
y1 = layer_1_z(x, w1, b1)
y2 = y1 - np.floor(y1)
return w2 * y2 + b2
def layer_2_activation(x, w1, b1, w2, b2):
y2 = layer_2(x, w1, b1, w2, b2)
# return 1 / (1 + np.exp(-y2))
return (y2 > 0) * 1
def loss(param):
w1, b1, w2, b2 = param
x = np.arange(0, 1000, 1)
y_hat = layer_2_activation(x, w1, b1, w2, b2)
y_true = (x % 2 > 0) * 1
return sum(np.square(y_hat - y_true))
# %%
from sko.GA import GA
ga = GA(func=loss, n_dim=4, size_pop=50, max_iter=100, lb=[1, 0, 1, 0], ub=[32, 1, 2, 1], precision=1)
best_x, best_y = ga.run()
print('best_x:', best_x, '\n', 'best_y:', best_y)
for x in range(1001, 1200):
y_hat = layer_2_activation(x, *best_x)
print('input:{},divide by 2:{}'.format(x, y_hat == 0))
input:1001,divide by 2:False input:1002,divide by 2:True
input:1003,divide by 2:False input:1004,divide by 2:True
input:1005,divide by 2:False input:1006,divide by 2:True
input:1007,divide by 2:False input:1008,divide by 2:True
input:1009,divide by 2:False input:1010,divide by 2:True
input:1011,divide by 2:False input:1012,divide by 2:True
input:1013,divide by 2:False input:1014,divide by 2:True
input:1015,divide by 2:False input:1016,divide by 2:True
input:1017,divide by 2:False input:1018,divide by 2:True
input:1019,divide by 2:False input:1020,divide by 2:True
input:1021,divide by 2:False input:1022,divide by 2:True
input:1023,divide by 2:False input:1024,divide by 2:True
input:1025,divide by 2:False input:1026,divide by 2:True
input:1027,divide by 2:False input:1028,divide by 2:True
input:1029,divide by 2:False input:1030,divide by 2:True
input:1031,divide by 2:False input:1032,divide by 2:True
input:1033,divide by 2:False input:1034,divide by 2:True
input:1035,divide by 2:False input:1036,divide by 2:True
input:1037,divide by 2:False input:1038,divide by 2:True
input:1039,divide by 2:False input:1040,divide by 2:True
input:1041,divide by 2:False input:1042,divide by 2:True
input:1043,divide by 2:False input:1044,divide by 2:True
input:1045,divide by 2:False input:1046,divide by 2:True
input:1047,divide by 2:False input:1048,divide by 2:True
input:1049,divide by 2:False input:1050,divide by 2:True
input:1051,divide by 2:False input:1052,divide by 2:True
input:1053,divide by 2:False input:1054,divide by 2:True
input:1055,divide by 2:False input:1056,divide by 2:True
input:1057,divide by 2:False input:1058,divide by 2:True
input:1059,divide by 2:False input:1060,divide by 2:True
input:1061,divide by 2:False input:1062,divide by 2:True
input:1063,divide by 2:False input:1064,divide by 2:True
input:1065,divide by 2:False input:1066,divide by 2:True
input:1067,divide by 2:False input:1068,divide by 2:True
input:1069,divide by 2:False input:1070,divide by 2:True
input:1071,divide by 2:False input:1072,divide by 2:True
input:1073,divide by 2:False input:1074,divide by 2:True
input:1075,divide by 2:False input:1076,divide by 2:True
input:1077,divide by 2:False input:1078,divide by 2:True
input:1079,divide by 2:False input:1080,divide by 2:True
input:1081,divide by 2:False input:1082,divide by 2:True
input:1083,divide by 2:False input:1084,divide by 2:True
input:1085,divide by 2:False input:1086,divide by 2:True
input:1087,divide by 2:False input:1088,divide by 2:True
input:1089,divide by 2:False input:1090,divide by 2:True
input:1091,divide by 2:False input:1092,divide by 2:True
input:1093,divide by 2:False input:1094,divide by 2:True
input:1095,divide by 2:False input:1096,divide by 2:True
input:1097,divide by 2:False input:1098,divide by 2:True
input:1099,divide by 2:False input:1100,divide by 2:True
input:1101,divide by 2:False input:1102,divide by 2:True
input:1103,divide by 2:False input:1104,divide by 2:True
input:1105,divide by 2:False input:1106,divide by 2:True
input:1107,divide by 2:False input:1108,divide by 2:True
input:1109,divide by 2:False input:1110,divide by 2:True
input:1111,divide by 2:False input:1112,divide by 2:True
input:1113,divide by 2:False input:1114,divide by 2:True
input:1115,divide by 2:False input:1116,divide by 2:True
input:1117,divide by 2:False input:1118,divide by 2:True
input:1119,divide by 2:False input:1120,divide by 2:True
input:1121,divide by 2:False input:1122,divide by 2:True
input:1123,divide by 2:False input:1124,divide by 2:True
input:1125,divide by 2:False input:1126,divide by 2:True
input:1127,divide by 2:False input:1128,divide by 2:True
input:1129,divide by 2:False input:1130,divide by 2:True
input:1131,divide by 2:False input:1132,divide by 2:True
input:1133,divide by 2:False input:1134,divide by 2:True
input:1135,divide by 2:False input:1136,divide by 2:True
input:1137,divide by 2:False input:1138,divide by 2:True
input:1139,divide by 2:False input:1140,divide by 2:True
input:1141,divide by 2:False input:1142,divide by 2:True
input:1143,divide by 2:False input:1144,divide by 2:True
input:1145,divide by 2:False input:1146,divide by 2:True
input:1147,divide by 2:False input:1148,divide by 2:True
input:1149,divide by 2:False input:1150,divide by 2:True
input:1151,divide by 2:False input:1152,divide by 2:True
input:1153,divide by 2:False input:1154,divide by 2:True
input:1155,divide by 2:False input:1156,divide by 2:True
input:1157,divide by 2:False input:1158,divide by 2:True
input:1159,divide by 2:False input:1160,divide by 2:True
input:1161,divide by 2:False input:1162,divide by 2:True
input:1163,divide by 2:False input:1164,divide by 2:True
input:1165,divide by 2:False input:1166,divide by 2:True
input:1167,divide by 2:False input:1168,divide by 2:True
input:1169,divide by 2:False input:1170,divide by 2:True
input:1171,divide by 2:False input:1172,divide by 2:True
input:1173,divide by 2:False input:1174,divide by 2:True
input:1175,divide by 2:False input:1176,divide by 2:True
input:1177,divide by 2:False input:1178,divide by 2:True
input:1179,divide by 2:False input:1180,divide by 2:True
input:1181,divide by 2:False input:1182,divide by 2:True
input:1183,divide by 2:False input:1184,divide by 2:True
input:1185,divide by 2:False input:1186,divide by 2:True
input:1187,divide by 2:False input:1188,divide by 2:True
input:1189,divide by 2:False input:1190,divide by 2:True
input:1191,divide by 2:False input:1192,divide by 2:True
input:1193,divide by 2:False input:1194,divide by 2:True
input:1195,divide by 2:False input:1196,divide by 2:True
input:1197,divide by 2:False input:1198,divide by 2:True
input:1199,divide by 2:False
Moreover, divide by other numbers (say, 7) is well, too:
import numpy as np
def layer_1_z(x, w1, b1):
return 1 / w1 * x + b1
def layer_2(x, w1, b1, w2, b2):
y1 = layer_1_z(x, w1, b1)
y2 = y1 - np.floor(y1)
return w2 * y2 + b2
def layer_2_activation(x, w1, b1, w2, b2):
y2 = layer_2(x, w1, b1, w2, b2)
# return 1 / (1 + np.exp(-y2))
return (y2 > 0) * 1
def loss(param):
w1, b1, w2, b2 = param
x = np.arange(0, 1000, 1)
y_hat = layer_2_activation(x, w1, b1, w2, b2)
y_true = (x % 7 > 0) * 1
return sum(np.square(y_hat - y_true))
# %%
from sko.GA import GA
ga = GA(func=loss, n_dim=4, size_pop=50, max_iter=100, lb=[1, 0, 1, 0], ub=[32, 1, 2, 1], precision=1)
best_x, best_y = ga.run()
print('best_x:', best_x, '\n', 'best_y:', best_y)
for x in range(1001, 1200):
y_hat = layer_2_activation(x, *best_x)
print('input:{},divide by 7:{}'.format(x, y_hat == 0))
input:1001,divide by 7:True input:1002,divide by 7:False
input:1003,divide by 7:False input:1004,divide by 7:False
input:1005,divide by 7:False input:1006,divide by 7:False
input:1007,divide by 7:False input:1008,divide by 7:True
input:1009,divide by 7:False input:1010,divide by 7:False
input:1011,divide by 7:False input:1012,divide by 7:False
input:1013,divide by 7:False input:1014,divide by 7:False
input:1015,divide by 7:True input:1016,divide by 7:False
input:1017,divide by 7:False input:1018,divide by 7:False
input:1019,divide by 7:False input:1020,divide by 7:False
input:1021,divide by 7:False input:1022,divide by 7:True
input:1023,divide by 7:False input:1024,divide by 7:False
input:1025,divide by 7:False input:1026,divide by 7:False
input:1027,divide by 7:False input:1028,divide by 7:False
input:1029,divide by 7:True input:1030,divide by 7:False
input:1031,divide by 7:False input:1032,divide by 7:False
input:1033,divide by 7:False input:1034,divide by 7:False
input:1035,divide by 7:False input:1036,divide by 7:True
input:1037,divide by 7:False input:1038,divide by 7:False
input:1039,divide by 7:False input:1040,divide by 7:False
input:1041,divide by 7:False input:1042,divide by 7:False
input:1043,divide by 7:True input:1044,divide by 7:False
input:1045,divide by 7:False input:1046,divide by 7:False
input:1047,divide by 7:False input:1048,divide by 7:False
input:1049,divide by 7:False input:1050,divide by 7:True
input:1051,divide by 7:False input:1052,divide by 7:False
input:1053,divide by 7:False input:1054,divide by 7:False
input:1055,divide by 7:False input:1056,divide by 7:False
input:1057,divide by 7:True input:1058,divide by 7:False
input:1059,divide by 7:False input:1060,divide by 7:False
input:1061,divide by 7:False input:1062,divide by 7:False
input:1063,divide by 7:False input:1064,divide by 7:True
input:1065,divide by 7:False input:1066,divide by 7:False
input:1067,divide by 7:False input:1068,divide by 7:False
input:1069,divide by 7:False input:1070,divide by 7:False
input:1071,divide by 7:True input:1072,divide by 7:False
input:1073,divide by 7:False input:1074,divide by 7:False
input:1075,divide by 7:False input:1076,divide by 7:False
input:1077,divide by 7:False input:1078,divide by 7:True
input:1079,divide by 7:False input:1080,divide by 7:False
input:1081,divide by 7:False input:1082,divide by 7:False
input:1083,divide by 7:False input:1084,divide by 7:False
input:1085,divide by 7:True input:1086,divide by 7:False
input:1087,divide by 7:False input:1088,divide by 7:False
input:1089,divide by 7:False input:1090,divide by 7:False
input:1091,divide by 7:False input:1092,divide by 7:True
input:1093,divide by 7:False input:1094,divide by 7:False
input:1095,divide by 7:False input:1096,divide by 7:False
input:1097,divide by 7:False input:1098,divide by 7:False
input:1099,divide by 7:True input:1100,divide by 7:False
input:1101,divide by 7:False input:1102,divide by 7:False
input:1103,divide by 7:False input:1104,divide by 7:False
input:1105,divide by 7:False input:1106,divide by 7:True
input:1107,divide by 7:False input:1108,divide by 7:False
input:1109,divide by 7:False input:1110,divide by 7:False
input:1111,divide by 7:False input:1112,divide by 7:False
input:1113,divide by 7:True input:1114,divide by 7:False
input:1115,divide by 7:False input:1116,divide by 7:False
input:1117,divide by 7:False input:1118,divide by 7:False
input:1119,divide by 7:False input:1120,divide by 7:True
input:1121,divide by 7:False input:1122,divide by 7:False
input:1123,divide by 7:False input:1124,divide by 7:False
input:1125,divide by 7:False input:1126,divide by 7:False
input:1127,divide by 7:True input:1128,divide by 7:False
input:1129,divide by 7:False input:1130,divide by 7:False
input:1131,divide by 7:False input:1132,divide by 7:False
input:1133,divide by 7:False input:1134,divide by 7:True
input:1135,divide by 7:False input:1136,divide by 7:False
input:1137,divide by 7:False input:1138,divide by 7:False
input:1139,divide by 7:False input:1140,divide by 7:False
input:1141,divide by 7:True input:1142,divide by 7:False
input:1143,divide by 7:False input:1144,divide by 7:False
input:1145,divide by 7:False input:1146,divide by 7:False
input:1147,divide by 7:False input:1148,divide by 7:True
input:1149,divide by 7:False input:1150,divide by 7:False
input:1151,divide by 7:False input:1152,divide by 7:False
input:1153,divide by 7:False input:1154,divide by 7:False
input:1155,divide by 7:True input:1156,divide by 7:False
input:1157,divide by 7:False input:1158,divide by 7:False
input:1159,divide by 7:False input:1160,divide by 7:False
input:1161,divide by 7:False input:1162,divide by 7:True
input:1163,divide by 7:False input:1164,divide by 7:False
input:1165,divide by 7:False input:1166,divide by 7:False
input:1167,divide by 7:False input:1168,divide by 7:False
input:1169,divide by 7:True input:1170,divide by 7:False
input:1171,divide by 7:False input:1172,divide by 7:False
input:1173,divide by 7:False input:1174,divide by 7:False
input:1175,divide by 7:False input:1176,divide by 7:True
input:1177,divide by 7:False input:1178,divide by 7:False
input:1179,divide by 7:False input:1180,divide by 7:False
input:1181,divide by 7:False input:1182,divide by 7:False
input:1183,divide by 7:True input:1184,divide by 7:False
input:1185,divide by 7:False input:1186,divide by 7:False
input:1187,divide by 7:False input:1188,divide by 7:False
input:1189,divide by 7:False input:1190,divide by 7:True
input:1191,divide by 7:False input:1192,divide by 7:False
input:1193,divide by 7:False input:1194,divide by 7:False
input:1195,divide by 7:False input:1196,divide by 7:False
input:1197,divide by 7:True input:1198,divide by 7:False
input:1199,divide by 7:False
Explanation:
I get 2 different solutions. They both are good:
1. sin as activation
2. floor(or int) as activation
It is impossible to find the best weights using gradient descent, and I use genetic algorithm (from scikit-opt)