私の解決策
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))
入力:1001、2で割る入力:1002、2で割る入力:1003、2で割る入力:1004、2で割る:真の入力:1005、2で割る入力:1006、割る2:真の入力:1007、2で割る入力:1008、2で割る入力:1009、2で割る入力:1010、2で割る入力:1011、2で割る入力:1012、2で割る:真の入力:1013、2で割る入力:1014、2で割る:真の入力:1015、2で割る:偽の入力:1016、2で割る:真の入力:1017、で割る2:False入力:1018、2で割る:1019、2で割る:False入力:1020、2で割る:True入力:1021、2で割る:Falseで割る:1022、2で割る:True入力: 1023、2で割る入力:1024、2で割る:真の入力:1025、2で割る入力:1026、2で割る:真の入力:1027、2で割る入力:1028、2で割る:真の入力:1029、2で割る:誤入力:1030、2で割る:真の入力:1031、2で割る入力:1032、2で割る:真の入力:1033、2で割る:偽の入力:1034、2で割る:真の入力:1035、 2:False入力で除算:1036、2:Trueで除算:1037、2:False入力で除算:1038、2:Trueで除算入力:1039、2:False入力で除算:1040、2:Trueで除算入力:1041、2で割る入力:1042、2で割る入力:1043、2で割る入力:1044、2で割る:真の入力:1045、2で割る入力:1046、割る2:2による入力:1047、2による分割入力:1048、2による分割:True入力:1049、2による分割入力:False入力:1050、2による分割:True入力:1051、2による分割入力:False :1052、2で割る:真の入力:1053、2で割る:偽の入力:1054、2で割る:真の入力:1055、2で割る:偽の入力:1056、2で割る:真の入力:1057、割る2:偽の入力:1058、2で割る:真の入力:1059、2で割る入力:060、2で割る:真の入力:1061、2で割る入力:1062、2で割る:真の入力:1063、2で割る入力:1064、 2:2で割る入力:1065、2で割る入力:1066、2で割る入力:1067、2で割る:偽入力:1068、2で割る入力:1069、2で割る:偽入力:1070、2で割る入力:1071、2で割る入力:1072、2で割る入力:1073、2で割る入力:False入力:1074、2で割る入力:1075、除算2:False入力:1076で除算、2:True入力:1077で除算、2:False入力で除算:1078、2:True入力で除算:1079、2:False入力で除算:1080、2:True入力で除算:1081、2で割る入力:1082、2で割る入力:1083、2で割る入力:1084、2で割る:真の入力:1085、2で割る入力:1086、で割る2:真の入力:1087、2で割る:誤入力:1088、2で割る:真の入力:1089、2で割る入力:090、2で割る:真の入力:1091、2で割る:偽の入力:1092、2で割る:真の入力:1093、 2:False入力で割る:1094、2:True入力で割る:1095、2:False入力で割る:1096、2:Trueで割る入力:1097、2:False入力で割る:1098、2:Trueで割る入力:1099、2で割る入力:1100、2で割る:真の入力:1101、2で割る入力:1102、2で割る:真の入力:1103、2で割る入力:1104、割る2:真の入力:1105、2で割る入力:1106、2で真の入力:1107、2で割る入力:108、2で割る:真の入力:1109、2で割る入力:1110、2で割る:真の入力:1111、2で割る:1112、2で割る:真の入力:1113、2で割る:偽の入力:1114、2で割る:真の入力:1115、で割る2:偽入力:1116、2で割る:真の入力:1117、2で割る入力:118、2で割る:真の入力:1119、2で割る入力:120、2で割る:真の入力:1121、2で割る入力:122、 2で割る:真の入力:1123、2で割る入力:124、2で割る:真の入力:1125、2で割る:偽の入力:1126、2で割る:真の入力:1127、2で割る:偽入力:1128、2で割る:真の入力:1129、2で割る:入力1130、2で割る:真の入力:1131、2で割る:偽の入力:1132、2で割る:真の入力:1133、割る2:False入力で1134、2:True入力で割る:1135、2:False入力で割る:1136、2:True入力で割る:1137、2:False入力で割る:1138、2:True入力で割る:1139、2で割る入力:1140、2で割る:真の入力:1141、2で割る入力:1142、2で割る:真の入力:1143、2で割る:偽の入力:1144、で割る2:真の入力:1145、2で割る:誤入力:1146、2で割る:真の入力:1147、2で割る入力:1148、2で割る:真の入力:1149、2で割る:偽の入力:1150、2で割る:真の入力:1151 2:False入力で分割:1152、2:True入力で分割:1153、2:False入力で分割:1:1、2で分割:True入力:1155、2で分割:False入力:1156、2で分割:True入力:1157、2で割る入力:1158、2で割る:真の入力:1159、2で割る入力:1160、2で割る:真の入力:1161、2で割る入力:1621、割る2:真の入力:1163、2で割る入力:1164、2で真の入力:1165、2で割る入力:1166、2で割る:真の入力:1167、2で割る入力:1168、2で割る:真の入力:1169、2:偽の入力:1170、2で割る:真の入力:1171、2で割る:偽の入力:1172、2で割る:真の入力:1173、で割る2:偽入力:1174、2で割る:真の入力:1175、2で割る入力:1176、2で割る入力:真の入力:1177、2で割る入力:1178、2で割る:真の入力:1179、2で割る入力:1180、 2:True入力:1181で除算、2:False入力で除算:1182、2:True入力で除算:1183、2:Falseで除算入力:1184、2で除算:True入力:1185、2:Falseで除算入力:1186、2で割る入力:1187、2で割る入力:1188、2で割る入力:1189、2で割る:誤入力:1190、2で割る入力:1191、除算2:False入力で1192、2:True入力で除算:1193、2:False入力で除算:1194、2:True入力で除算:1195、2:False入力で除算:1196、2:True入力で除算:1197、2で割る入力:1198、2で割る:真の入力:1199、2で割る:偽真の入力:1179、2で割る入力:1180、2で割る:真の入力:1181、2で割る入力:1182、2で割る:真の入力:1183、2で割る入力:1184、 2で割る:真の入力:1185、2で割る入力:1186、2で割る:真の入力:1187、2で割る:偽の入力:1188、2で割る:真の入力:1189、2で割る:偽入力:1190、2で割る入力:1191、2で割る入力:1192、2で割る入力:1193、2で割る:偽の入力:1194、2で割る:真の入力:1195、割る2:False入力:1196、2:True入力で分割:1197、2:False入力で分割:1198、2:True入力:1199、2:Falseで分割真の入力:1179、2で割る入力:1180、2で割る:真の入力:1181、2で割る入力:1182、2で割る:真の入力:1183、2で割る入力:1184、 2で割る:真の入力:1185、2で割る入力:1186、2で割る:真の入力:1187、2で割る:偽の入力:1188、2で割る:真の入力:1189、2で割る:偽入力:1190、2で割る入力:1191、2で割る入力:1192、2で割る入力:1193、2で割る:偽の入力:1194、2で割る:真の入力:1195、割る2:False入力:1196、2:True入力で分割:1197、2:False入力で分割:1198、2:True入力:1199、2:Falseで分割真の入力:1187、2で割る入力:1188、2で割る:真の入力:1189、2で割る入力:1190、2で割る:真の入力:1191、2で割る入力:1192、 2で割る:真の入力:1193、2で割る入力:1194、2で割る:真の入力:1195、2で割る入力:1196、2で割る:真の入力:1197、2で割る:偽入力:1198、2で割る:真の入力:1199、2で割る:偽真の入力:1187、2で割る入力:1188、2で割る:真の入力:1189、2で割る入力:1190、2で割る:真の入力:1191、2で割る入力:1192、 2で割る:真の入力:1193、2で割る入力:1194、2で割る:真の入力:1195、2で割る入力:1196、2で割る:真の入力:1197、2で割る:偽入力:1198、2で割る:真の入力:1199、2で割る:偽
さらに、他の数値(たとえば、7)による除算も適切です。
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))
入力:1001、7で割る:True入力:1002、7で割る:False入力:1003、7で割る:False入力:1004、7で割る:False入力:1005、7で割る:False入力:1006、除算7:False入力で分割:1007、7:False入力で分割:1008、7:True入力で分割:1009、7:False入力で分割:1010、7:False入力で分割:1011、7:False入力で分割:1012、7:False入力で除算:1013、7:False入力で除算:1014、7:False入力で除算:1015、7:True入力で除算:1016、7:False入力で除算:1017、除算7:False入力:1018、7で割る:False入力:1019、7で割る:False入力:1020、7で割る:False入力:1021、7で割る:False入力:1022、7で割る:True入力: 1023、7:False入力で分割:1024、7:False入力で分割:1025、7:False入力で分割:1026、7:False入力で分割:1027、7:False入力で分割:1028、7で分割:誤入力:1029、7で割る:真の入力:1030、7で割る:False入力:1031、7で割る:False入力:1032、7で割る:False入力:1033、7で割る:False入力:1034、7で割る:False入力:1035、 7:False入力で割る:1036、7:True入力で割る:1037、7:False入力で割る:1038、7:False入力で割る:1039、7:False入力で割る:1040、7:Falseで割る入力:1041、7で割る:False入力:1042、7で割る:False入力:1043、7で割る:真の入力:1044、7で割る:False入力:1045、7で割る:False入力:1046、割る7:False入力:1047で除算、7:False入力:1048で除算、7:False入力で除算:1049、7:False入力で除算:1050、7:False入力で除算:1051、7:False入力で除算:1052、7で割る:False入力:1053、7で割る:False入力:1054、7で割る:False入力:1055、7で割る:False入力:1056、7で割る:False入力:1057、で割る7:真の入力:1058、7:False入力で除算:1059、7:False入力で除算:060、7:False入力で除算:1061、7:False入力で除算:1062、7:False入力で除算:1063、7:Falseで除算入力:1064、7で割る:真の入力:1065、7で割る:偽の入力:1066、7で割る:偽の入力:1067、7で割る:偽の入力:1068、7で割る:偽の入力:1069、割る7:False入力で分割:1070、7:False入力で分割:1071、7で分割:True入力:1072、7で分割:False入力:1073、7で分割:False入力:1074、7:False入力で分割:1075、7で割る:False入力:1076、7で割る:False入力:1077、7で割る:False入力:1078、7で割る:True入力:1079、7で割る:False入力:1080、で割る7:False入力:1081、7:False入力:1082、7:False入力:1083、7:False入力:1084、7:False入力:1085、7:True入力で割る: 1086、7で割る:誤入力:1087、7で割る:False入力:1088、7で割る:False入力:1089、7で割る:False入力:1090、7で割る:False入力:1091、7で割る:False入力:1092 7で除算:真の入力:1093、7で除算:偽の入力:1094、7で除算:偽の入力:1095、7で除算:偽の入力:1096、7で除算:偽の入力:1097、7で除算:偽入力:1098、7で割る入力:1099、7で割る:真の入力:1100、7で割る:偽の入力:1101、7で割る:偽の入力:1102、7で割る:偽の入力:1103、割る7:False入力:1104、7:False入力:1105、7:False入力:1106、7:True入力:1107、7:False入力:1108、7:False入力で分割:1109、7で割る:偽の入力:1110、7で割る:偽の入力:1111、7で割る:偽の入力:1112、7で割る:偽の入力:1113、7で割る:真の入力:1114、で割る7:誤入力:1115、7で割る:偽の入力:1116、7で割る:偽の入力:1117、7で割る:偽の入力:1118、7で割る:偽の入力:1119、7で割る:偽の入力:1120、7で割る:True入力:1121、7で割る入力:1222、7で割る入力:False入力:1123、7で割る入力:False入力:1124、7で割る入力:False入力:1125、7で割る入力:False入力:1126、除算7:誤入力:1127、7:誤入力:1128、7:誤入力:1129、7:誤入力:1130、7:誤入力:1131、7:誤入力で除算:1132、7で割る:偽の入力:1133、7で割る:偽の入力:1134、7で割る:真の入力:1135、7で割る:偽の入力:1136、7で割る:偽の入力:1137、で割る7:False入力:1138、7:False入力:1139、7:False入力:1140、7:False入力で割る:1141、7:True入力:1142、7:False入力で割る: 1143、7で割る:誤入力:1144、7で割る:偽の入力:1145、7で割る:偽の入力:1146、7で割る:偽の入力:1147、7で割る:偽の入力:1148、7で割る:真の入力:1149、7で割る:偽入力:1150、7で割る:1151、7で割る:1152、7で割る:偽の入力:1153、7で割る:偽の入力:1154、7で割る:偽の入力:1155 、7で除算:真の入力:1156、7で除算:偽の入力:1157、7で除算:偽の入力:1158、7で除算:偽の入力:1159、7で除算:偽の入力:1160、7で除算:誤った入力:1161,7で割る:偽の入力:1162,7で割る:真の入力:1163,7で割る:偽の入力:1164,7で割る:偽の入力:1165,7で割る:偽の入力:1166、 7で割る:入力1167、7で割る入力:1168、7で割る入力:1169、7で割る:真の入力:1170、7で割る入力:偽の入力:1171、7で割る:偽入力:1172、7で割る:誤入力:1173、7で割る:偽の入力:1174、7で割る:偽の入力:1175、7で割る:偽の入力:1176、7で割る:真の入力:1177、7で割る:偽の入力:1178、 7:False入力で除算:1179、7:False入力で除算:1180、7:False入力で除算:181、7:False入力で除算:1822、7:False入力で除算:1833、7:Trueで除算入力:1184、7で割る入力:1185、7で割る入力:偽の入力:1186、7で割る入力:1871、7で割る入力:偽の入力:1188、7で割る:入力1189、割る7:False入力で1190、7:True入力で割る:1191、7:False入力で割る:1192、7:False入力で割る:1193、7:False入力で割る:1194、7:False入力で割る:1195、7:False入力で除算:1196、7:False入力で除算:1197、7:True入力で除算:1198、7:False入力で除算:1199、7:Falseで除算7で割る:偽の入力:1175、7で割る:偽の入力:1176、7で割る:真の入力:1177、7で割る:偽の入力:1178、7で割る:偽の入力:1179、7で割る:偽入力:1180、7で割る入力:1811、7で割る入力:偽の入力:1182、7で割る入力:偽の入力:1183、7で割る入力:真の入力:1184、7で割る入力:偽の入力:1185、割る7:False入力:1186、7:False入力:1187、7:False入力:1188、7:False入力:1189、7:False入力:1190、7:True入力で除算:1191、7:False入力で分割:1192、7:False入力で分割:1193、7:False入力で分割:1194、7:False入力で分割:1195、7:False入力で分割:1196、分割7:False入力:1197、7で割る:True入力:1198、7で割る:False入力:1199、7で割る:False7で割る:偽の入力:1175、7で割る:偽の入力:1176、7で割る:真の入力:1177、7で割る:偽の入力:1178、7で割る:偽の入力:1179、7で割る:偽入力:1180、7で割る入力:1811、7で割る入力:偽の入力:1182、7で割る入力:偽の入力:1183、7で割る入力:真の入力:1184、7で割る入力:偽の入力:1185、割る7:False入力:1186、7:False入力:1187、7:False入力:1188、7:False入力:1189、7:False入力:1190、7:True入力で除算:1191、7:False入力で分割:1192、7:False入力で分割:1193、7:False入力で分割:1194、7:False入力で分割:1195、7:False入力で分割:1196、分割7:False入力:1197、7で割る:True入力:1198、7で割る:False入力:1199、7で割る:False誤入力:1178、7で割る:偽の入力:1179、7で割る:偽の入力:1180、7で割る:偽の入力:1181、7で割る:偽の入力:1182、7で割る:偽の入力:1183、 7で割る:真の入力:1184、7で割る入力:1185、7で割る入力:偽の入力:1186、7で割る入力:偽の入力:1187、7で割る入力:偽の入力:1188、7で割る:偽入力:1189、7で割る入力:1190、7で割る:真の入力:1191、7で割る入力:1192、7で割る入力:偽入力:1193、7で割る入力:偽の入力:1194、割る7:誤入力:1195、7:誤入力:1196、7:誤入力:1197、7:誤入力:1198、7:誤入力:1199、7:誤誤入力:1178、7で割る:偽の入力:1179、7で割る:偽の入力:1180、7で割る:偽の入力:1181、7で割る:偽の入力:1182、7で割る:偽の入力:1183、 7で割る:真の入力:1184、7で割る入力:1185、7で割る入力:偽の入力:1186、7で割る入力:偽の入力:1187、7で割る入力:偽の入力:1188、7で割る:偽入力:1189、7で割る入力:1190、7で割る:真の入力:1191、7で割る入力:1192、7で割る入力:偽入力:1193、7で割る入力:偽の入力:1194、割る7:誤入力:1195、7:誤入力:1196、7:誤入力:1197、7:誤入力:1198、7:誤入力:1199、7:誤7:False入力で分割する:1185、7:False入力で分割する:1186、7:False入力で分割する:1187、7:False入力で分割する:1188、7:False入力で分割する:1189、7:Falseで分割する入力:1190、7で割る:真の入力:1191、7で割る:偽の入力:1192、7で割る:偽の入力:1193、7で割る:偽の入力:1194、7で割る:偽の入力:1195、割る7:False入力:1196、7:False入力:1197、7:True入力:1198、7:False入力:1199、7:Falseで除算7:False入力で分割する:1185、7:False入力で分割する:1186、7:False入力で分割する:1187、7:False入力で分割する:1188、7:False入力で分割する:1189、7:Falseで分割する入力:1190、7で割る:真の入力:1191、7で割る:偽の入力:1192、7で割る:偽の入力:1193、7で割る:偽の入力:1194、7で割る:偽の入力:1195、割る7:False入力:1196、7:False入力:1197、7:True入力:1198、7:False入力:1199、7:Falseで除算7で割る:真の入力:1198、7で割る:偽の入力:1199、7で割る:偽7で割る:真の入力:1198、7で割る:偽の入力:1199、7で割る:偽
説明:
2つの異なるソリューションがあります。彼らは両方とも良いです:
1.アクティベーションとしての罪
2. アクティベーションとしての床(または整数)
勾配降下を使用して最適な重みを見つけることは不可能であり、遺伝的アルゴリズムを使用します(scikit-optから)