聊聊常规编程和机器学习的一点不同!
点击上方关注,All in AI中国
当我听说机器学习时,我无法抑制心中的惊奇。我无法理解这一事实,这与我已经习惯的普通软件程序不同,我甚至不需要提前教计算机“如何“详细了解所有未来场景。
工程学使我们能够突破人类能力的极限。无论是高性能机械机械还是编码硅片,我们用对自然的理解来实现我们的目的。而到目前为止,计算机一直是最大限度地利用大自然的力量来帮助人类推动其能力极限,即许多可由计算机执行的任务永远不能由人或一组人快速有效地执行。正如史蒂夫乔布斯所说,电脑就像是我们大脑的自行车。
我从小就对电脑很着迷。 2001年,当我用BASIC编写了一个程序来添加两个数字时,我第一次与计算机进行了交互。令我惊讶的是,无论添加是什么样子,计算机都会立即回答。
当我听说机器学习时,我无法抑制惊奇,这与我习惯的普通软件程序不同,我甚至不必通过计算机预先知道所有未来场景的“详细程度”。有一种方法可以让计算机自己学会如何解决问题。这对人类来说是一次巨大的飞跃。
什么是机器学习?
“机器学习”这个词并不新鲜。它是由亚瑟·塞缪尔于1959年创造的,借鉴了计算机科学、统计学、线性代数和概率论等不同领域的理解,并应用于解决实际问题。机器学习使计算机能够从历史数据中学习并制定可用于在将来解决类似问题的解决方案,而不需要教授计算机所有可能情景的组合。而机器学习的实际应用是,甚至不可能为这个问题阐明一个明确的数学解决方案。
如果以下情况,现实问题是机器学习应用的候选者 -
- 历史数据存在巨大数量
- 数据中存在模式
- 很难用数学方法确定解决方案
它与传统编程有何不同?
传统编程的方法是为计算机提供一组用于定义的一组场景的指令。之后,计算机将利用其计算能力,帮助人们更快、更有效地处理数据。在机器学习中,计算机会抛出大量数据,而计算机又处理所有数据,并提出称为训练模型(解决方案)的东西。然后,该模型用于解决现实世界中看不见的问题。
例子
让我们把用一个玩具问题来说明。这问题需要一个输入数字并尝试除以3和5。如果数字可以被3整除,那么它会输出'fizz',如果它可以被5整除,那么它会输出'buzz',如果它可以被两者都整除那么它会输出'fizzbuzz'。如果它不能被3或5中的任何一个整除,则输出“其他”。它被称为Fizzbuzz游戏。
常规编程
传统编程非常容易为计算机提供一组指令,因为我们只有4个场景需要验证并根据它来输出。 python代码可以写成如下所示,但如果你不编码,你可以跳过读取代码。
def fizzbuzz(n): # if the number is divisible by 3 as well as by 5 and returns # "FizzBuzz" if n % 3 == 0 and n % 5 == 0: return 'FizzBuzz'# If the first condition is not satisfied then it checks if it is # divisible by 3 and return "Fizz" elif n % 3 == 0: return 'Fizz'# If both of the above tests are not satisfying, then it will check # whether it is divisible by 5 and return "Buzz" elif n % 5 == 0: return 'Buzz'# If all the conditions above do not satisfy then it returns "Other" else: return 'Other'
机器学习
假设我们已经有很多数字,其输出已经知道,可能是'fizz','buzz'或者'fizzbuzz'。我们现在需要做的就是编写机器学习代码并提供(训练)可用数据。然后通过使用看不见的数据进行测试来验证我们是否已成功创建模型。如果模型使用训练模型提供输出而不实际计算结果,那么我们就达到了目的。
我们将使用Google的Tensorflow库来实现此目的。以下是实现中的一些代码片段。
同样,如果您不编码,可以跳过代码。整个工作代码可以在我的Github帐户中找到。
a.创建模型
# Placeholders are the type of variables nodes where data can be # fed from outside when we actually run the model #Placeholder for input data inputTensor = tf.placeholder(tf.float32, [None, 10]) # Placeholder for output data outputTensor = tf.placeholder(tf.float32, [None, 4]) # The number of neurons which 1st hidden neurons will have i.e. 1000 NUM-HIDDEN-NEURONS-LAYER-1 = 1000 # Learning rate, which will be later used to optimize for optimizer function # Learning rate defines at what rate the optimizer function will move towards minima per iteration # Less than optimum learning rate will slow down the process whereas higher learning rate will have chances of # skipping the minima all together. So it will never converge rather it will keep on going back and forth. LEARNING-RATE = 0.05 # Initializing the weights to Normal Distribution # The weights will keep on adjusting towards optimum values in each iteration. Conceptually, weights determine the # discrimination factor of a particular variable in the neural network. More the weight more will be its # contribution in determining the solution. def init-weights(shape): return to.Variable(tf.random-normal(shape,stddev=0.01)) # Initializing the input to hidden layer weights # We will need a total of 10(input layer number) * 100(number of hidden layers) input-hidden-weights = init-weights([10, NUM-HIDDEN-NEURONS-LAYER-1]) # Initializing the hidden to output layer weights #, In this case, we will need 100(number of hidden neurons layers) * 4(output neurons, we have only 4 categories) hidden-output-weights = init-weights([NUM-HIDDEN-NEURONS-LAYER-1, 4]) # Computing values at the hidden layer # Matrix multiplication is done and then rectifier neural network activation function is used # for regularization of the resulting multiplication hidden-layer = tf.nn.relu(tf.matmul(inputTensor, input-hidden-weights)) # Computing values at the output layer # Matrix multiplication of hidden layer and output weights it done. output-layer = tf.matmul(hidden-layer, hidden-output-weights) # Defining Error Function # Error function computes the difference between actual output and model output. # Here we are calculating the error in the output as compared to the output label error-function = tf.reduce-mean(tf.nn.softmax-cross-entropy-with-logits(logits=output-layer, labels=outputTensor)) # Defining Learning Algorithm and Training Parameters # We are using Gradient Descent function to optimize the error or to reach the minima. training = tf.train.GradientDescentOptimizer(LEARNING-RATE).minimize(error-function) # Prediction Function prediction = tf.argmax(output-layer, 1)
b.对模型进行训练
NUM-OF-EPOCHS = 5000
BATCH-SIZE = 128
training-accuracy = []
with tf.Session() as sess:
# Set Global Variables ?
# We had only defined the model previously. To run the model, all the variables need to be initialized and run.
# Actual computation can only start after the initialization.
tf.global-variables-initializer().run()
for epoch in tqdm-notebook(range(NUM-OF-EPOCHS)):
#Shuffle the Training Dataset at each epoch
#Shuffling is done to have even more randmized data, which adds to the generalization of model even more.
p = np.random.permutation(range(len(processedTrainingData)))
processedTrainingData = processedTrainingData[p]
processedTrainingLabel = processedTrainingLabel[p]
# Start batch training
# With batch size of 128, there will be total of 900/128 runs in each epoch where 900 is the total
# training data.
for start in range(0, len(processedTrainingData), BATCH-SIZE):
end = start + BATCH-SIZE
sess.run(training, feed-dict={inputTensor: processedTrainingData[start:end],
outputTensor: processedTrainingLabel[start:end]})
# Training accuracy for an epoch
# We are checking here the accuracy of model after each epoch
training-accuracy.append(np.mean(np.argmax(processedTrainingLabel, axis=1) ==
sess.run(prediction, feed-dict={inputTensor: processedTrainingData,
outputTensor: processedTrainingLabel})))
# Testing
predictedTestLabel = sess.run(prediction, feed-dict={inputTensor: processedTestingData})
C.对模型进行测试
wrong = 0 right = 0 predictedTestLabelList = [] #Comparing the predicted value with the actual label in training data for i,j in zip(processedTestingLabel,predictedTestLabel): predictedTestLabelList.append(decodeLabel(j)) if np.argmax(i) == j: right = right + 1 else: wrong = wrong + 1 print("Errors: " + str(wrong), " Correct :" + str(right)) print("Testing Accuracy: " + str(right/(right+wrong)*100))
d.结果:
错误:2 正确:98
测试精度:98.0%
结论
每次重新洗牌后,我们反复输送相同的数据5000次。每次运行后,我们通过测量测试数据中的错误率来测量模型的准确度。可以看出,该模型的准确率为98%。我已经在每次迭代后绘制了误差图。它越接近1,我们的模型就越好。这是它的样子:
最后的话
如上所述,在这个特殊的玩具箱中 - 传统的程序总能提供正确的输出,而机器学习可能达不到100%的准确度。
现在想象一下,您运营像Netflix这样拥有数百万客户的公司的场景。每个客户都有一组独特的偏好。例如,有些人可能喜欢纪录片和喜剧电影,在星期二观看纪录片,周日看喜剧。而其他人则在周六晚上其他人狂欢,喜欢在周日看恐怖片,等等。你可以想象,当有很多变量决定确切的偏好时,记录每个人的所有习惯是多么复杂。因为如果你想向每个顾客推荐他/她将要观看的电影,那么你必须知道该人的确切偏好。
对于传统编程,这个问题变得越来越困难,因为:
- 你不知道是什么决定了一个人的观看习惯。
- 即使您知道,该解决方案也不会一次扩展到数百万用户,因为对于每个人,您必须根据他/她的习惯编写单独的解决方案。
这就是实现机器学习的地方。通常,在这种情况下,机器学习将在两个前提下进行训练:
- 根据你过去的数据,你最可能看哪部电影?
- 像你这样的人现在在看什么?
PS:文章中使用的完整代码可以在这里找到。(https://www.linkedin.com/pulse/how-different-conventional-programming-machine-learning-sharma/)
参考:
- https://www.amazon.com/Pattern-Recognition-Learning-Information-Statistics/dp/0387310738
- https://www.youtube.com/watch?v=mbyG85GZ0PI&index=1&list=PLD63A284B7615313A