机器学习的奇偶数预测不起作用(成功率50%)

11
我对机器学习非常陌生。我试图创建一个模型来预测数字是否为偶数。
我使用了这段代码https://machinelearningmastery.com/tutorial-first-neural-network-python-keras/,并根据我的需求进行了修改。
问题是成功率约为50%,等同于随机猜测。
你知道该怎么做才能让它工作吗?
from keras.models import Sequential
from keras.layers import Dense
import numpy
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

X = list(range(1000))
Y = [1,0]*500
# create model
model = Sequential()
model.add(Dense(12, input_dim=1, init='uniform', activation='relu'))
model.add(Dense(8, init='uniform', activation='relu'))
model.add(Dense(1, init='uniform', activation='sigmoid'))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X, Y, epochs=150, batch_size=10,  verbose=2)
# calculate predictions
predictions = model.predict(X)
# round predictions
rounded = [round(x[0])for x in predictions]
print(rounded)


>>> [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

似乎用神经网络做这件事情有点奇怪 :/ 而且我认为你的代码并不完全正确。你正在构建的模型期望有12个输入,如果只有一个数字,那么这些输入是什么?尝试以下操作:MNIST Tensorflow,因为Keras是基于Tensorflow构建的,所以应该可以实现。 - SBylemans
您可以尝试简单的特征转换:x -> (-1)^x。在这里,符号“^”表示-1的x次幂。 - eozd
任何从事人工智能领域的人都应该解决并理解这个非常好的问题。 - prosti
6个回答

6

神经网络并不擅长判断一个数字是否为偶数,至少在输入表示只有整数的情况下如此。神经网络擅长发现和组合线性决策边界。对于所有自然数而言,如果要检查一个数字是否为偶数,则有无限数量的决策边界需要检查。但是,如果你只让你的神经网络在所有数字的子集上工作,那么它就可以正常工作。但是,你基本上需要为你想要测试的每个数字在你的输入层中添加一个神经元。因此,在0 <= n < 1000的情况下,你需要在输入层中拥有一千个神经元。这并不是神经网络的一个很好的例子。

如果你改变输入的表示形式为数字的二进制表示,则NN将更容易地检测数字是否为偶数。例如:

X = [
  [0, 0, 0], # 0
  [0, 0, 1], # 1
  [0, 1, 0], # 2
  [0, 1, 1], # 3
  [1, 0, 0], # 4
  [1, 0, 1], # 5
  [1, 1, 0], # 6
  [1, 1, 1]  # 7
]

Y = [1, 0, 1, 0, 1, 0, 1, 0]

正如你所看到的,这现在是一个相当简单的问题:基本上是最后一个二进制数字的倒数。这是预处理输入的一个例子,以创建一个更容易由神经网络解决的问题。


1
非常棒的回答。确认了表达方式的重要性。我基本上使用了你的模型来创作我的回答。 - prosti

5
我认为你应该阅读感知器异或问题,以了解单个感知器的工作原理及其限制。
判断一个数字是否为偶数是一个二元分类问题,具有一维输入;在分类问题中,神经网络通过边界分离类别。思考这个问题的一种方法是将其一维输入映射到两个维度的输入中,通过向添加的维度添加输入数字(例如,将7映射到[7,7])并查看散点图中的偶数和奇数向量的外观。
如果您在Jupyter笔记本中运行以下代码
%matplotlib inline
import matplotlib.pyplot as plt

X = list(range(-20, 20))
evens = [x for x in X if x % 2 == 0]
odds = [x for x in X if x % 2 != 0]
data = (evens, odds)
colors = ("green", "blue")
groups = ("Even", "Odd") 

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
for data, color, group in zip(data, colors, groups):
    x = data
    ax.scatter(x, x, alpha=0.8, c=color, edgecolors='none', s=30, label=group)
plt.title('Even/Odd numbers')
plt.legend(loc=2)
plt.show()

data = (evens, odds)
fig2 = plt.figure()
ax = fig2.add_subplot(1, 1, 1)
for data, color, group in zip(data, colors, groups):
    x = data
    y = [abs(i) if i%2==0 else -abs(i) for i in data]
    ax.scatter(x, y, alpha=0.8, c=color, edgecolors='none', s=30, label=group)
plt.title('Even/Odd numbers (Separatable)')
plt.legend(loc=2)
plt.show()

您将看到类似以下图像的内容:

Evens and Odds numbers

在第一张图中,很难确定偶数向量和奇数向量之间的边界。但是,如果将第二维度的数字映射到其相应的负数,则可以轻松地在两个类(偶数和奇数向量)之间绘制边界。因此,如果您将输入数据转换为两个维度,并根据偶数或奇数否定第二个维度值,则神经网络可以学习如何分离偶数和奇数向量类。
您可以尝试以下代码,您会发现该网络将学习并收敛到几乎100%的准确性。
import numpy
from keras.models import Sequential
from keras.layers import Dense

# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

X = numpy.array([[x, x if x%2 == 0 else -x] for x in range(1000)])
Y = [1,0]*500

# create model
model = Sequential()
model.add(Dense(12, input_dim=2, init='uniform', activation='relu'))
model.add(Dense(8, init='uniform', activation='relu'))
model.add(Dense(1, init='uniform', activation='sigmoid'))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X, Y, epochs=50, batch_size=10,  verbose=2)
# Calculate predictions
predictions = model.predict(X)

请注意,基于奇偶性将数字转换为负空间的方法也适用于一维空间,但使用具有两个维度向量的散点图更容易进行演示。

5

以下是我在Python 3中使用Keras创建用于分类奇偶数的模型的方法。

第一层隐藏层只使用了1个神经元,有32个输入。输出层只有两个神经元,用于进行one-hot编码,分别表示0和1。

from keras.models import Sequential
from keras.layers import Dense
from keras.utils import to_categorical


# Helper function to convert a number 
# to its fixed width binary representation
def conv(x):
  a = format(x, '032b')
  l = list(str(a))
  l = np.array(list(map(int, l)))
  return l

# input data
data = [conv(i) for i in range(100000)]
X = np.array(data)


Y= list() # empty list of results
for v in range(100000):
  Y.append( to_categorical(v%2, 2) )

Y = np.array(Y) # we need np.array


# Sequential is a fully connected network
model = Sequential()

# 32 inputs and 1 neuron in the first layer (hidden layer)
model.add(Dense(1, input_dim=32, activation='relu'))

# 2 output layer 
model.add(Dense(2, activation='sigmoid'))


model.compile(loss='binary_crossentropy', 
              optimizer='adam', 
              metrics=['accuracy'])

# epochs is the number of times to retrain over the same data set
# batch_size is how may elements to process in parallel at one go
model.fit(X, Y, epochs=5, batch_size=100, verbose=1)
weights, biases = model.layers[0].get_weights()
print("weights",weights.size, weights, "biases", biases)
model.summary()

Epoch 1/5
100000/100000 [==============================] - 3s 26us/step - loss: 0.6111 - acc: 0.6668
Epoch 2/5
100000/100000 [==============================] - 1s 13us/step - loss: 0.2276 - acc: 1.0000
Epoch 3/5
100000/100000 [==============================] - 1s 13us/step - loss: 0.0882 - acc: 1.0000
Epoch 4/5
100000/100000 [==============================] - 1s 13us/step - loss: 0.0437 - acc: 1.0000
Epoch 5/5
100000/100000 [==============================] - 1s 13us/step - loss: 0.0246 - acc: 1.0000
weights 32 [[-4.07479703e-01]
 [ 2.29798079e-01]
 [ 4.12091196e-01]
 [-1.86401993e-01]
 [ 3.70162904e-01]
 [ 1.34553611e-02]
 [ 2.01252878e-01]
 [-1.00370705e-01]
 [-1.41752958e-01]
 [ 7.27931559e-02]
 [ 2.55639553e-01]
 [ 1.90407157e-01]
 [-2.42316410e-01]
 [ 2.43226111e-01]
 [ 2.22285628e-01]
 [-7.04377817e-05]
 [ 2.20522008e-04]
 [-1.48785894e-05]
 [-1.15533156e-04]
 [ 1.16850446e-04]
 [ 6.37861085e-05]
 [-9.74628711e-06]
 [ 3.84256418e-05]
 [-6.19597813e-06]
 [-7.05791535e-05]
 [-4.78575275e-05]
 [-3.07796836e-05]
 [ 3.26417139e-05]
 [-1.51580054e-04]
 [ 1.27965177e-05]
 [ 1.48101550e-04]
 [ 3.18456793e+00]] biases [-0.00016785]
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_49 (Dense)             (None, 1)                 33        
_________________________________________________________________
dense_50 (Dense)             (None, 2)                 4         
=================================================================
Total params: 37
Trainable params: 37
Non-trainable params: 0

以下是预测结果:

print(X[0:1])
scores = model.predict(X[0:1])
print(scores)
print(np.argmax(scores))

print(X[1:2])
scores = model.predict(X[1:2])
print(scores)
print(np.argmax(scores))

[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
[[0.9687797  0.03584918]]
0
[[0 0 0 0 0 0 0 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.00130448 0.9949934 ]]
1

1

机器学习的目标是在具有特征/模式(X为你)的数据上预测标签(Y为你)。

对于你来说,问题在于你的X只是一个不断增长的列表,没有特定的模式顺序或任何解释。

因此,你试图要求统计算法解释完全随机的事情,这是不可能的

从 Kaggle 的 Titanic 数据集 开始尝试机器学习的最初阶段,它是 ML 的参考平台:

https://www.kaggle.com/upendr/titanic-machine-learning-from-disaster/data

下载它,通过pandas加载并尝试相同的算法。

您的X将是每个特征,如班级、年龄、性别等,而您的Y是幸存,如果他活着,则值为1,否则为0。您将尝试通过年龄、性别等模式来确定他是否活着。

我还可以推荐看看Andrew Ng:机器学习课程,这将解释一切,并且非常适合初学者。

玩得开心!:)


没有一门课程或者多门课程可以解释给你所有的东西! - prosti

1

我不惊讶它不起作用——神经网络就是不这样工作的。

你必须更好地了解将什么作为输入传递给神经网络。

当你传递数字时,它必须具有一些“意义”。这意味着:如果一个数字大于另一个数字,它应该引起某些事情。比如年龄->金钱,其中应该有任何依赖关系。

但是当寻找奇数时,这个意义更加抽象。老实说,你应该将输入视为独立的字符串值。

也许,作为输入,请尝试:

X = [[math.floor(item/2), item/2 - math.floor(item/2)] for item in range(1000)]

检查网络是否能“理解”“如果第二个值大于零,则该数字为奇数”。

继续阅读以获得更好的感觉 :)

编辑:

@MIlano 完整代码如下

from keras.models import Sequential
from keras.layers import Dense
import numpy
import math
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

X = numpy.array([[math.floor(item/2), item/2 - math.floor(item/2)] for item in range(1000)])

Y = [1, 0]*500
# create model
model = Sequential()
model.add(Dense(12, input_shape=(2,), init='uniform', activation='relu'))
model.add(Dense(8, init='uniform', activation='relu'))
model.add(Dense(1, init='uniform', activation='sigmoid'))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X, Y, epochs=150, batch_size=10,  verbose=2)
# calculate predictions
predictions = model.predict(X)
# round predictions
rounded = [round(x[0])for x in predictions]
print(rounded)

我尝试了一下,但是返回了以下错误信息:ValueError: 检查模型输入时出错:您传递给模型的NumPy数组列表大小与模型期望的大小不同。预期应该看到1个数组,但实际上得到了以下1000个数组的列表:[array([[0.],... - Milano

0

这并不是我见过的神经网络最奇怪的应用。最接近的例子可能是2006年的《一个组合神经网络解决质数测试问题》,它使用神经网络来解决更复杂的数论问题。

研究的结果是它可以被训练,我建议你尝试使用类似的结构,但正如论文所述,这种问题有更好的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接