<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Step 1
Step1:  Step 2
Step2:  Step 3
<ASSISTANT_TASK:>
Python Code:
X = np.array([[0,0,1],
            [0,1,1],
            [1,0,1],
            [1,1,1]])
                
Y = np.array([[0],
            [1],
            [1],
            [0]])
X
Y
Explanation: Step 1: Collect Data
End of explanation
num_epochs = 60000
#initialize weights
syn0 = 2*np.random.random((3,4)) - 1
syn1 = 2*np.random.random((4,1)) - 1
syn0
syn1
def nonlin(x,deriv=False):
    if(deriv==True):
        return x*(1-x)
    return 1/(1+np.exp(-x))
Explanation: Step 2: build model
End of explanation
for epoch in range(num_epochs):
    #feed forward through layers 1, 2 & 3
    l0 = X                        # the input layer
    l1 = nonlin(np.dot(l0, syn0)) # hidden layer
    l2 = nonlin(np.dot(l1, syn1)) # final, hence output layer
    
    # by how much did we miss the target value?
    l2_error = Y - l2
    l2_delta = l2_error * nonlin(l2, deriv=True)
    
    # propgating to the next layer
    l1_error = np.dot(l2_delta, syn1.T)
    l1_delta = l1_error * nonlin(l1, deriv=True)
    
    # updating weights
    syn1 += l1.T.dot(l2_delta)
    syn0 += l0.T.dot(l1_delta)
    
    if (epoch% 10000) == 0:
        print("Error:", (np.mean(np.abs(l2_error))))
        #print(l1_error)
        print('============')
Explanation: Step 3: train model
End of explanation
<END_TASK>