microsoft / AI-For-Beginners

12 Weeks, 24 Lessons, AI for All!
https://microsoft.github.io/AI-For-Beginners/
MIT License
34.05k stars 5.66k forks source link

03 Perceptron/Perceptron. ipynb [in11] cannot run correctly #233

Open mouseart opened 1 year ago

mouseart commented 1 year ago

I am trying to run

https://github.com/microsoft/AI-For-Beginners/blob/main/lessons/3-NeuralNetworks/03-Perceptron/Perceptron.ipynb of [In11] Code:

def train_graph(positive_examples, negative_examples, num_iterations = 100):
    num_dims = positive_examples.shape[1]
    weights = np.zeros((num_dims,1)) # initialize weights

    pos_count = positive_examples.shape[0]
    neg_count = negative_examples.shape[0]

    report_frequency = 15;
    snapshots = []

    for i in range(num_iterations):
        pos = random.choice(positive_examples)
        neg = random.choice(negative_examples)

        z = np.dot(pos, weights)   
        if z < 0:
            weights = weights + pos.reshape(weights.shape)

        z  = np.dot(neg, weights)
        if z >= 0:
            weights = weights - neg.reshape(weights.shape)

        if i % report_frequency == 0:             
            pos_out = np.dot(positive_examples, weights)
            neg_out = np.dot(negative_examples, weights)        
            pos_correct = (pos_out >= 0).sum() / float(pos_count)
            neg_correct = (neg_out < 0).sum() / float(neg_count)
            snapshots.append((np.copy(weights),(pos_correct+neg_correct)/2.0))

    return np.array(snapshots)

snapshots = train_graph(pos_examples,neg_examples)

def plotit(pos_examples,neg_examples,snapshots,step):
    fig = pylab.figure(figsize=(10,4))
    fig.add_subplot(1, 2, 1)
    plot_boundary(pos_examples, neg_examples, snapshots[step][0])
    fig.add_subplot(1, 2, 2)
    pylab.plot(np.arange(len(snapshots[:,1])), snapshots[:,1])
    pylab.ylabel('Accuracy')
    pylab.xlabel('Iteration')
    pylab.plot(step, snapshots[step,1], "bo")
    pylab.show()
def pl1(step): plotit(pos_examples,neg_examples,snapshots,step)

Encountered an error:

--------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[10], line 32
     28             snapshots.append((np.copy(weights),(pos_correct+neg_correct)[/](https://file+.vscode-resource.vscode-cdn.net/)2.0))
     30     return np.array(snapshots)
---> 32 snapshots = train_graph(pos_examples,neg_examples)
     34 def plotit(pos_examples,neg_examples,snapshots,step):
     35     fig = pylab.figure(figsize=(10,4))

Cell In[10], line 30, in train_graph(positive_examples, negative_examples, num_iterations)
     27         neg_correct = (neg_out < 0).sum() [/](https://file+.vscode-resource.vscode-cdn.net/) float(neg_count)
     28         snapshots.append((np.copy(weights),(pos_correct+neg_correct)[/](https://file+.vscode-resource.vscode-cdn.net/)2.0))
---> 30 return np.array(snapshots)

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 2 dimensions. The detected shape was (7, 2) + inhomogeneous part.

May I ask how to handle it to resolve it? Thank you very much.

Harrison-LUO commented 1 year ago

First I encountered the same issue when installing the environment, then I tried to manually configure the environment and dependencies. During the running, I encountered the same problem with you, and I searched stackoverflow found a similar problem the solution is to use an older version, so i refer to the repository file(.devcontainer/environment.yml) to replace numpy with the 1.22.3 version, and it working for me.

mouseart commented 1 year ago

首先我在安装环境时遇到了同样的问题,然后我尝试手动配置环境和依赖项。 在运行过程中,我遇到了和你同样的问题,我搜索了stackoverflow发现了类似的问题解决方案是使用旧的版本,所以我参考存储库文件(.devcontainer/environment.yml)将numpy替换为1.22 .3版本,它对我有用。

Thank you very much. Your suggestion has solved my problem.

Deepwind64 commented 11 months ago

For anyone who don't want to change numpy version, I've correct the old code. You can replace the original code with the code below.

def train_graph(positive_examples, negative_examples, num_iterations = 100):
    num_dims = positive_examples.shape[1]
    weights = np.zeros((num_dims,1)) # initialize weights

    pos_count = positive_examples.shape[0]
    neg_count = negative_examples.shape[0]

    report_frequency = 15
    snapshots = []

    for i in range(num_iterations):
        pos = random.choice(positive_examples)
        neg = random.choice(negative_examples)

        z = np.dot(pos, weights)   
        if z < 0:
            weights = weights + pos.reshape(weights.shape)

        z  = np.dot(neg, weights)
        if z >= 0:
            weights = weights - neg.reshape(weights.shape)

        if i % report_frequency == 0:             
            pos_out = np.dot(positive_examples, weights)
            neg_out = np.dot(negative_examples, weights)        
            pos_correct = (pos_out >= 0).sum() / float(pos_count)
            neg_correct = (neg_out < 0).sum() / float(neg_count)
            snapshots.append((np.copy(weights),(pos_correct+neg_correct)/2.0))
    return snapshots

snapshots = train_graph(pos_examples,neg_examples)

def plotit(pos_examples,neg_examples,snapshots,step):
    fig = pylab.figure(figsize=(10,4))
    fig.add_subplot(1, 2, 1)
    plot_boundary(pos_examples, neg_examples, snapshots[step][0])
    fig.add_subplot(1, 2, 2)
    # pylab.plot(np.arange(len(snapshots[:,1])), snapshots[:,1])
    pylab.plot(np.arange(len(snapshots)), [[acc] for arr,acc in snapshots])
    pylab.ylabel('Accuracy')
    pylab.xlabel('Iteration')
    pylab.plot(step, snapshots[step,1], "bo")
    pylab.show()
def pl1(step): plotit(pos_examples,neg_examples,snapshots,step)
TonyBolos commented 5 months ago

The error you're encountering seems to stem from an inconsistency in the shape of the arrays being appended to snapshots. Specifically, the error message suggests that there's an issue with setting an array element with a sequence, resulting in an inhomogeneous shape after 2 dimensions.

To fix this issue, you need to ensure that the elements appended to snapshots have consistent shapes. Looking at your code, it appears that you're appending a tuple containing weights (which is a 2D array) and the average accuracy. However, the concatenation of pos_correct and neg_correct inside the tuple might be causing the inconsistency.

Here's my code i copied from the compiler:

-------------------------------------------------

def train_graph(positive_examples, negative_examples, num_iterations = 100):

num_dims = positive_examples.shape[1]
weights = np.zeros((num_dims,1)) # initialize weights

pos_count = positive_examples.shape[0]
neg_count = negative_examples.shape[0]

report_frequency = 15;
snapshots = []

for i in range(num_iterations):
    pos = random.choice(positive_examples)
    neg = random.choice(negative_examples)

    z = np.dot(pos, weights)   
    if z < 0:
        weights = weights + pos.reshape(weights.shape)

    z  = np.dot(neg, weights)
    if z >= 0:
        weights = weights - neg.reshape(weights.shape)

    if i % report_frequency == 0:             
        pos_out = np.dot(positive_examples, weights)
        neg_out = np.dot(negative_examples, weights)        
        pos_correct = (pos_out >= 0).sum() / float(pos_count)
        neg_correct = (neg_out < 0).sum() / float(neg_count)
        accuracy = (pos_correct + neg_correct) / 2.0  # Calculate average accuracy
        snapshots.append((np.copy(weights), accuracy))

return np.array(snapshots)

snapshots = train_graph(pos_examples, neg_examples)

def plotit(pos_examples, neg_examples, snapshots, step): fig = pylab.figure(figsize=(10,4)) fig.add_subplot(1, 2, 1) plot_boundary(pos_examples, neg_examples, snapshots[step][0]) fig.add_subplot(1, 2, 2) pylab.plot(np.arange(len(snapshots[:,1])), snapshots[:,1]) pylab.ylabel('Accuracy') pylab.xlabel('Iteration') pylab.plot(step, snapshots[step,1], "bo") pylab.show()

def pl1(step): plotit(pos_examples, neg_examples, snapshots, step) Online Python compiler (interpreter) to run Python online.

Write Python 3 code in this online editor and run it.

print("Try programiz.pro"

-------------------------------------------------

This code ensures that the average accuracy is calculated correctly and appended to snapshots along with weights, resulting in consistent shapes for each element in snapshots.

I hope it workes/help :).