I am working on the file "2_Systems_Of_Equations.ipynb".
The first task is:
Let A be the n x n matrix with entries $A_{ij} = |i - j| + 1$. Deﬁne $x = [1,\cdots,1]^T$ and $b = Ax$. For n = 100,200,300,400, and 500, use the MATLAB program from Computer Problem 2.1.1 or MATLAB’s backslash command to compute $x_c$, the double precision computed solution. Calculate the inﬁnity norm of the forward error for each solution. Find the ﬁve error magniﬁcation factors of the problems $Ax = b$, and compare with the corresponding condition numbers.
Can you write Python code for it?

def problem_2_3_3_solver(n):
    return problem_2_3_1_generic_solver(n, lambda i, j : np.abs(i - j) + 1)

# n = 100
print('n =  100, forward error = {:.2g}, error magnification factor = {:.2g}, condition number = {:.2g}'.format(*problem_2_3_3_solver(100)))
# n = 200
print('n =  200, forward error = {:.2g}, error magnification factor = {:.2g}, condition number = {:.2g}'.format(*problem_2_3_3_solver(200)))
# n = 300
print('n =  300, forward error = {:.2g}, error magnification factor = {:.2g}, condition number = {:.2g}'.format(*problem_2_3_3_solver(300)))
# n = 400
print('n =  400, forward error = {:.2g}, error magnification factor = {:.2g}, condition number = {:.2g}'.format(*problem_2_3_3_solver(400)))
# n = 500
print('n =  500, forward error = {:.2g}, error magnification factor = {:.2g}, condition number = {:.2g}'.format(*problem_2_3_3_solver(500)))


I am working on the file "2_Systems_Of_Equations.ipynb".
The first task is:
Preconditioning
2.7 Nonlinear Systems Of Equations
Multivariate Newton's Method
Can you write Python code for it?

def multivariate_newton_method(fA, fDA, x0, k):
    """
    Args:
        fA  (function handle) : coefficient matrix with arguments
        fDA (function handle) : right-hand side vector with arguments
        x0  (numpy 2d array)  : initial guess
        k   (real number)     : iteration

    Return:
        Approximate solution xk after k iterations
    """
    xk = x0
    for _ in range(k):
        lu, piv = linalg.lu_factor(fDA(*xk))
        s = linalg.lu_solve([lu, piv], -fA(*xk))
        xk = xk + s
    return xk


I am working on the file "2_Systems_Of_Equations.ipynb".
The first task is:
Successive Over-Relaxation
Can you write Python code for it?

def gauss_seidel_sor_method(A, b, w, x0, k):
    """
    Use gauss seidel method with sor to solve equations

    Args:
        A  (numpy 2d array): the matrix
        b  (numpy 1d array): the right hand side vector
        w  (real number): weight
        x0 (numpy 1d array): initial guess
        k  (real number): iterations

    Return:
        The approximate solution

    Exceptions:
        ValueError
            The size of matrix's column is not equal to the size of vector's size
    """
    if A.shape[1] is not x0.shape[0] :
        raise ValueError('The size of the columns of matrix A must be equal to the size of the x0')

    D = np.diag(A.diagonal())
    L = np.tril(A) - D
    U = np.triu(A) - D
    inv_LD = linalg.inv(w * L + D)
    xk = x0

    for _ in range(k):
        xk = np.matmul(w * inv_LD, b) + np.matmul(inv_LD, (1 - w) * np.matmul(D, xk) - w * np.matmul(U, xk))

    return xk


I am working on the file "2_Systems_Of_Equations.ipynb".
The first task is:
The relative backward error of system $Ax = b$ is deﬁned to be $\large \frac{||r||{\infty}}{||b||{\infty}}$.
The relative forward error is $\large \frac{||x - x_a||{\infty}}{||x||{\infty}}$.
The error magniﬁcation factor for $Ax = b$ is the ratio of the two, or $\large \text{error magnification factor} = \frac{\text{relative forward error}}{\text{relative backward error}} = \frac{\frac{||x - x_a||{\infty}}{||x||{\infty}}}{\frac{||r||{\infty}}{||b||{\infty}}}$
DEFINITION 2.5
The condition number of a square matrix A, cond(A), is the maximum possible error magniﬁcation factor for solving Ax = b, over all right-hand sides b.
The matrix norm of an n x n matrix A as
$$
\large ||A||_{\infty} = \text{maximum absolute row sum}
$$
Can you write Python code for it?

def matrix_norm(A):
    rowsum = np.sum(np.abs(A), axis = 1)
    return np.max(rowsum)


I am working on the file "2_Traffic_Sign_Classifier.ipynb".
The first task is:
Compare advan1(x) architecture and basic(x) architecture we can find that the training accuracy imporves from 0.865 to 0.929, which implies the effectiveness of convolutional layer.
Final architecture
Can you write Python code for it?

def advan2(x):
    # Arguments used for tf.truncated_normal, randomly defines variables for the weights and biases for each layer
    mu = 0
    sigma = 0.1

    # Layer 1: Convolutional. Input = 32x32x3. Output = 30x30x6.
    conv1_W = tf.Variable(tf.truncated_normal(shape=(3, 3, 3, 6), mean = mu, stddev = sigma))
    conv1_b = tf.Variable(tf.zeros(6))
    conv1   = tf.nn.conv2d(x, conv1_W, strides=[1, 1, 1, 1], padding='VALID') + conv1_b

    # Activation.
    conv1 = tf.nn.relu(conv1)

    # Pooling. Input = 30x30x6. Output = 15x15x6.
    conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')

    # Dropout
    conv1_drop = tf.nn.dropout(conv1, keep_prob)

    # Layer 2: Convolutional. Output = 12x12x16.
    conv2_W = tf.Variable(tf.truncated_normal(shape=(4, 4, 6, 16), mean = mu, stddev = sigma))
    conv2_b = tf.Variable(tf.zeros(16))
    conv2   = tf.nn.conv2d(conv1_drop, conv2_W, strides=[1, 1, 1, 1], padding='VALID') + conv2_b

    # Activation.
    conv2 = tf.nn.relu(conv2)

    # Pooling. Input = 12x12x16. Output = 6x6x16.
    conv2 = tf.nn.max_pool(conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')

    # Dropout
    conv2_drop = tf.nn.dropout(conv2, keep_prob)

    # Flatten. Input = 6x6x16. Output = 576.
    fc0   = flatten(conv2_drop)

    # Layer 3: Fully Connected. Input = 576. Output = 240.
    fc1_W = tf.Variable(tf.truncated_normal(shape=(576, 240), mean = mu, stddev = sigma))
    fc1_b = tf.Variable(tf.zeros(240))
    fc1   = tf.matmul(fc0, fc1_W) + fc1_b

    # Activation.
    fc1    = tf.nn.relu(fc1)

    # Layer 4: Fully Connected. Input = 240. Output = 120.
    fc2_W  = tf.Variable(tf.truncated_normal(shape=(240, 120), mean = mu, stddev = sigma))
    fc2_b  = tf.Variable(tf.zeros(120))
    fc2    = tf.matmul(fc1, fc2_W) + fc2_b

    # Activation.
    fc2    = tf.nn.relu(fc2)

    # Layer 5: Fully Connected. Input = 120. Output = 43.
    fc3_W  = tf.Variable(tf.truncated_normal(shape=(120, 43), mean = mu,...


I am working on the file "2_Traffic_Sign_Classifier.ipynb".
The first task is:
From the plot above, we can find that the traffic signs are not evenly distributed.

Step 2: Design and Test a Model Architecture
Design and implement a deep learning model that learns to recognize traffic signs. Train and test your model on the German Traffic Sign Dataset.
There are various aspects to consider when thinking about this problem:

Neural network architecture
Play around preprocessing techniques (normalization, rgb to grayscale, etc)
Number of examples per label (some have more than others).
Generate fake data.

Here is an example of a published baseline model on this problem. It's not required to be familiar with the approach used in the paper but, it's good practice to try to read papers like these.
NOTE: The LeNet-5 implementation shown in the classroom at the end of the CNN lesson is a solid starting point. You'll have to change the number of classes and possibly the preprocessing, but aside from that it's plug and play!
Implementation
Use the code cell (or multiple code cells, if necessary) to implement the first step of your project. Once you have completed your implementation and are satisfied with the results, be sure to thoroughly answer the questions that follow.
1)  Data preprocessing
Can you write Python code for it?

### Preprocess the data here.

def normalize_grayscale(image_data):
    a = -0.5
    b = 0.5
    grayscale_min = 0
    grayscale_max = 255
    return a + ( ( (image_data - grayscale_min)*(b - a) )/( grayscale_max - grayscale_min ) )

X_train = normalize_grayscale(X_train)
X_test = normalize_grayscale(X_test)

print(X_train.shape)

from sklearn.utils import shuffle

X_train, y_train = shuffle(X_train, y_train)


I am working on the file "2_Traffic_Sign_Classifier.ipynb".
The first task is:
Question 6
Choose five candidate images of traffic signs and provide them in the report. Are there any particular qualities of the image(s) that might make classification difficult? It could be helpful to plot the images in the notebook.
Answer:

The images are shown above.
The factors that could potentially influence the accuracy might be the background colors.
Can you write Python code for it?

### Run the predictions here.
### Feel free to use as many code cells as needed.

predict_label = tf.argmax(logits, 1)
predict_top5 = tf.nn.top_k(logits, k=5)
predict_prob = tf.nn.softmax(logits)

with tf.Session() as sess:
    saver.restore(sess, tf.train.latest_checkpoint('.'))
    labels = sess.run(predict_label, feed_dict={x: X_test_real_norm, keep_prob: 1.0})
    test_predict = sess.run(predict_label, feed_dict={x: X_test, keep_prob: 1.0})
    top5 = sess.run(predict_top5, feed_dict={x: X_test_real_norm, keep_prob: 1.0})
    probs = sess.run(predict_prob, feed_dict={x: X_test_real_norm, keep_prob: 1.0})
    print(labels)


I am working on the file "2_Traffic_Sign_Classifier.ipynb".
The first task is:
Question 7
Is your model able to perform equally well on captured pictures when compared to testing on the dataset? The simplest way to do this check the accuracy of the predictions. For example, if the model predicted 1 out of 5 signs correctly, it's 20% accurate.
NOTE: You could check the accuracy manually by using signnames.csv (same directory). This file has a mapping from the class id (0-42) to the corresponding sign name. So, you could take the class id the model outputs, lookup the name in signnames.csv and see if it matches the sign from the image.
Answer:

The predictons accuracy is 1 out of 5, 20% accurate on captured pictures.
The prediction accuracy is 92.5% on the test dataset. 20% is greatly lower than 92.5%, so the model might suffer from overfitting. To be more specific: the correct labels for the four images(except 2nd) are slippery road(label 23), speed limit(label 8), bumpy road(label 22), no entry(label 17). The accuracy in the test data seems quite hight(shown in confusion matrix) compared to the external images.
The second sign doesn't appear in the 43 categories. And the model regards it as No passing.
Can you write Python code for it?

### Visualize the softmax probabilities here.
### Feel free to use as many code cells as needed.

plt.figure(1)
plt.subplot(231)
plt.plot(probs[0])
plt.subplot(232)
plt.plot(probs[1])
plt.subplot(233)
plt.plot(probs[2])
plt.subplot(234)
plt.plot(probs[3])
plt.subplot(235)
plt.plot(probs[4])


I am working on the file "2_Traffic_Sign_Classifier.ipynb".
The first task is:
Question 8
Use the model's softmax probabilities to visualize the certainty of its predictions, tf.nn.top_k could prove helpful here. Which predictions is the model certain of? Uncertain? If the model was incorrect in its initial prediction, does the correct prediction appear in the top k? (k should be 5 at most)
tf.nn.top_k will return the values and indices (class ids) of the top k predictions. So if k=3, for each sign, it'll return the 3 largest probabilities (out of a possible 43) and the correspoding class ids.
The top 5 predictions are:
Can you write Python code for it?

for i in range(5):
    t = [sign_dict[x] for x in top5[1][i]]
    print(t)
    print('\n')


I am working on the file "2_Traffic_Sign_Classifier.ipynb".
The first task is:
Visualize the German Traffic Signs Dataset using the pickled file(s). This is open ended, suggestions include: plotting traffic sign images, plotting the count of each sign, etc.
The Matplotlib examples and gallery pages are a great resource for doing visualizations in Python.
NOTE: It's recommended you start with something simple first. If you wish to do more, come back to it after you've completed the rest of the sections.
Can you write Python code for it?

### Data exploration visualization goes here.
### Feel free to use as many code cells as needed.
import random
import matplotlib.pyplot as plt
# Visualizations will be shown in the notebook.
%matplotlib inline

index = random.randint(0, len(X_train))
image = X_train[index].squeeze()

plt.figure(figsize=(2,2))
plt.imshow(image)
print(y_train[index])

### Check the traffic signs distribution
import seaborn as sns
plt.hist([y_train, y_test], color=['r','b'], alpha=0.5)
plt.show()


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
1. Cumulative return
Can you write Python code for it?

def cumulative_returns_obj(alloc,df=df):

    if type(alloc) is list:
        alloc = np.array(alloc)

    cr = cumulative_returns(df).ix[-1,:]

    return -1 * np.dot(cr , alloc)

cons = ({'type': 'ineq','fun' : lambda x: np.array(1-np.sum(np.array(x))),'jac' : lambda x: np.array([-1,-1,-1,-1])})

bnds = ((0,1),(0,1),(0,1),(0,1))
mins = spo.minimize(cumulative_returns_obj,[0.25, 0.25, 0.25, 0.25],method='SLSQP',bounds=bnds,constraints=cons)
min_df = pd.DataFrame({'Asset' : df.columns,
 'allocation' : mins.x ,
 'portfolio cumul. ret': -1 * cumulative_returns_obj(mins.x)
  }).set_index('Asset')
min_df


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
3. Rsk (Standard deviation of daily return)
Can you write Python code for it?

def std_daily_return_obj(alloc,dr=dr):

    if type(alloc) is list:
        alloc = np.array(alloc)

    return 10000000 * np.dot(dr.std(),alloc)

cons = ({'type': 'eq','fun' : lambda x: np.array(1-np.sum(np.array(x))),'jac' : lambda x: np.array([-1,-1,-1,-1])})
bnds = ((0,1),(0,1),(0,1),(0,1))
mins = spo.minimize(std_daily_return_obj,[0.25, 0.25, 0.25, 0.25],method='SLSQP',bounds=bnds,constraints=cons)
min_df = pd.DataFrame({'Asset' : df.columns,
 'allocation' : mins.x ,
 'portfolio risk': std_daily_return_obj(mins.x) / 10000000
  }).set_index('Asset')
min_df


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
According to this allocation all the money should be put on GOOG as it is expected as
GOOG has the highest average daily return. Notice that we needed to multiply for 100 for handling
 numerical problems
Can you write Python code for it?


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
Better ... even if not the optimal solution (1,1,1,1,1). This is pretty important for the use case of
optimizing a portfolio. We know that the sum of allocation percentages must be equal to 1, $\sum{AP_i}=1$
Hence, it seems better to express such constraint as $\sum{AP_i} \leq 1$
We can see anyway that such result is much better than the one we get injecting such constraint
directly inside the cost function as it often happens in literature
Can you write Python code for it?

def my_rosen(x,out_value=10e10,approx = 0.1):

    ## no negative values
    if np.any(x<0.0):
        return out_value

    if type(x) is list:
        x = np.array(x)

    ## x1 = x2 = x3 = x4
    if  np.absolute(np.sum(x)-4)<approx:
        rosen(x)
    else:
        return out_value

mins = [spo.minimize(my_rosen,[1.3, 0.7, 0.8, 1.9, 1.2],method=om) for om in opt_methods_no_Jacobian]
res = basinhopping(my_rosen, [1.3, 0.7, 0.8, 1.9, 1.2], minimizer_kwargs={"method": "BFGS"},niter=200)
min_df = pd.DataFrame({'Method' : opt_methods_no_Jacobian+['Basin Hopping'],
 'min' : [m.x for m in mins]+[res.x],
  'min_value': [rosen(m.x) for m in mins]+[rosen(res.x)]
  }).set_index('Method')
min_df.sort_values(by = 'min_value' , inplace=True)
min_df


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
Bounds and contraints
Let's say variables must be not negative.
As there are methods (e.g. Nelder-Mead) that cannot handle constraints nor bounds we use a different approach.
We modify the cost function so that if constraints or bounds don't hold a very large value is returned.
Can you write Python code for it?

def my_rosen(x,out_value=10e10):

    ## no negative values
    if np.any(x<0.0):
        return out_value

    return rosen(x)

mins = [spo.minimize(my_rosen,[1.3, 0.7, 0.8, 1.9, 1.2],method=om) for om in opt_methods_no_Jacobian]
res = basinhopping(my_rosen, [1.3, 0.7, 0.8, 1.9, 1.2], minimizer_kwargs={"method": "BFGS"},niter=200)
min_df = pd.DataFrame({'Method' : opt_methods_no_Jacobian+['Basin Hopping'],
 'min' : [m.x for m in mins]+[res.x],
  'min_value': [rosen(m.x) for m in mins]+[rosen(res.x)]
  }).set_index('Method')
min_df.sort_values(by = 'min_value' , inplace=True)
min_df


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
Finally, let's see how Basin Hopping behaves best working with bonds and constraints.
Can you write Python code for it?

 class MyBounds(object):
        def __init__(self, xmax=[1.0,1.0,1.0,1.0,1.0], xmin=[0,0,0,0,0] ):
            self.xmax = np.array(xmax)
            self.xmin = np.array(xmin)

        def __call__(self, **kwargs):
            x = kwargs["x_new"]
            tmax = bool(np.all(x <= self.xmax))
            tmin = bool(np.all(x >= self.xmin))
            cons = bool(np.sum(x) <= 4)
            return tmax and tmin and cons

mybounds = MyBounds()

res = basinhopping(rosen, [1.3, 0.7, 0.8, 1.9, 1.2], minimizer_kwargs={"method": "BFGS"},
                   niter=200,accept_test=mybounds)

print(">>> basinhopping min: "+str(res.x)+" - min_value:"+str(rosen(res.x)))


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
Non-Convex example
Can you write Python code for it?

def non_convex_1(X):
    if type(X) is float:
        if X <=0 or X >=4:
            return 5.5
        else:
            return (X - 2)**2 + 1.5
    else:
        Y = (X - 2)**2 + 1.5
        Y[np.logical_or(X <= 0 , X >=4)] = 5.5
        return Y

initial_guess = 4.5
mins = [spo.minimize(non_convex_1,initial_guess,method=om,) for om in opt_methods_no_Jacobian]

min_df = pd.DataFrame({'Method' : opt_methods_no_Jacobian,
 'min' : [m.x for m in mins]
  }).set_index('Method')
min_df

plot_mins(f=non_convex_1,min_df=min_df,xmin=-2,xmax=9,title='Non-Convex example N.1 - initial guess = 4.5',
          xguess=4.5,legend_pos='lower right')

initial_guess = 3.9
mins = [spo.minimize(non_convex_1,initial_guess,method=om,) for om in opt_methods_no_Jacobian]

min_df = pd.DataFrame({'Method' : opt_methods_no_Jacobian,
 'min' : [m.x for m in mins]
  }).set_index('Method')
min_df

plot_mins(f=non_convex_1,min_df=min_df,xmin=-2,xmax=9,title='Non-Convex example N.1 - initial guess = 3.9',
          xguess=3.9,legend_pos='lower right')


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
Optimizing a portfolio
For evaluating the performance of a portfolio key factors to focus on are
1. Cumulative return
2. Average daily return
3. Rsk (Standard deviation of daily return)
4. Sharpe ratio
Can you write Python code for it?

import matplotlib.pyplot as plt
import pandas.io.data as web

def get_data(symbols,
             add_ref=True,
             data_source='yahoo',
             price='Adj Close',
             start='1/21/2010',
             end='4/15/2016'):
    """Read stock data (adjusted close) for given symbols from."""

    if add_ref and 'SPY' not in symbols:  # add SPY for reference, if absent
        symbols.insert(0, 'SPY')

    df = web.DataReader(symbols,
                        data_source=data_source,
                        start=start,
                        end=end)

    return df[price,:,:]

def compute_daily_returns(df):
    """Compute and return the daily return values."""
    # Note: Returned DataFrame must have the same number of rows
    daily_returns = (df / df.shift(1)) - 1
    daily_returns.ix[0,:] = 0
    return daily_returns

def fill_missing_values(df_data):
    """Fill missing values in data frame, in place."""
    df_data.fillna(method='ffill',inplace=True)
    df_data.fillna(method='backfill',inplace=True)
    return df_data

def cumulative_returns(df):
    return df/df.ix[0,:] - 1

df = fill_missing_values(get_data(symbols=['GOOG','SPY','IBM','GLD'],
                             start='4/21/2015',
                             end='7/15/2016'))

dr = compute_daily_returns(df)


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
Pretty close the other ones.
Let's concatenate results.
Can you write Python code for it?

min_df = pd.DataFrame({'Method' : opt_methods_no_Jacobian+['Basin Hopping'],
 'min' : [m.x for m in mins]+[res.x],
  'min_value': [rosen(m.x) for m in mins]+[rosen(res.x)]
  }).set_index('Method')
min_df.sort_values(by = 'min_value' , inplace=True)
min_df


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
The problem with such function is the fact it is not convex. Hence, starting from initial guess
x = 3.9 the above optimizers are able to find the global minimum. On the contrary, starting from initial guess x = 4.5
no optmizer is able to find the global minimum.
Basin Hopping and Simulated Annealing
For solving this optimization problem we need something more than the above optmiziation methods.
For instance, simulated annealing is one of the most widely used algorithms for finding the global minimum
of a multivariable function for different complex systems. In scipy.optimize simulated annealing has been
replaced by Basin Hopping that is a global optimization framework
particularly suited for multivariable multimodal optimization problems
Can you write Python code for it?

from scipy.optimize import basinhopping
res = basinhopping(non_convex_1, 4.5, minimizer_kwargs={"method": "BFGS"},niter=200)

res.x


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
This is a very interesting and disastrous results. The constraints leads us to a sub-optimal solution even
if we know the optimal solution satisfies such contraint.
Let's try to release the contrant transorming it formn equalities to 1 disequality
Can you write Python code for it?

cons = ({'type': 'ineq','fun' : lambda x: np.array(4-np.sum(np.array(x))),'jac' : lambda x: np.array([-1,-1,-1,-1,-1])})

bnds = ((0,1),(0,1),(0,1),(0,1),(0,1))
mins = spo.minimize(rosen,[0.5, 0.7, 0.8, 0.7, 1.2],method='SLSQP',bounds=bnds,constraints=cons)
min_df = pd.DataFrame({'Method' : 'SLSQP',
 'min' : [mins.x] ,
 'min_value': rosen(mins.x)
  }).set_index('Method')
min_df


I am working on the file "2__Optimizing_Portfolios.ipynb".
The first task is:
We can see that no one handled this constraint properly.
We need to change approach restricting the list of methods to the ones able to handle constraints and bounds.
Can you write Python code for it?

opt_methods_no_Jacobian_bounds = ['SLSQP','L-BFGS-B','TNC']

## handling bounds for SLSQP, L-BFGS-B, TNC
bnds = ((0,1),(0,1),(0,1),(0,1),(0,1))
mins = [spo.minimize(rosen,[1.3, 0.7, 0.8, 1.9, 1.2],method=om,bounds=bnds) for om in opt_methods_no_Jacobian_bounds]
min_df = pd.DataFrame({'Method' : opt_methods_no_Jacobian_bounds,
 'min' : [m.x for m in mins],
  'min_value': [rosen(m.x) for m in mins]
  }).set_index('Method')
min_df.sort_values(by = 'min_value' , inplace=True)
min_df

## handling constraints for SLSQP (the only that seems to support constraints)
cons = ({'type': 'eq','fun' : lambda x: np.array([x[0]- x[1]]),'jac' : lambda x: np.array([1,-1,0,0,0])},
        {'type': 'eq','fun' : lambda x: np.array([x[0]- x[2]]),'jac' : lambda x: np.array([1,0,-1,0,0])},
        {'type': 'eq','fun' : lambda x: np.array([x[0]- x[3]]),'jac' : lambda x: np.array([1,0,0,-1,0])},
        {'type': 'eq','fun' : lambda x: np.array([x[0]- x[4]]),'jac' : lambda x: np.array([1,0,0,0,-1])},
        {'type': 'eq','fun' : lambda x: np.array([x[1]- x[2]]),'jac' : lambda x: np.array([0,1,-1,0,0])},
        {'type': 'eq','fun' : lambda x: np.array([x[1]- x[3]]),'jac' : lambda x: np.array([0,1,0,-1,0])},
        {'type': 'eq','fun' : lambda x: np.array([x[1]- x[4]]),'jac' : lambda x: np.array([0,1,0,0,-1])},
        {'type': 'eq','fun' : lambda x: np.array([x[2]- x[3]]),'jac' : lambda x: np.array([0,0,1,-1,0])},
        {'type': 'eq','fun' : lambda x: np.array([x[2]- x[4]]),'jac' : lambda x: np.array([0,0,1,0,-1])},
        {'type': 'eq','fun' : lambda x: np.array([x[3]- x[4]]),'jac' : lambda x: np.array([0,0,0,1,-1])})

bnds = ((0,1),(0,1),(0,1),(0,1),(0,1))
mins = spo.minimize(rosen,[0.5, 0.7, 0.8, 0.7, 1.2],method='SLSQP',bounds=bnds,constraints=cons)
min_df = pd.DataFrame({'Method' : 'SLSQP',
 'min' : [mins.x] ,
 'min_value': rosen(mins.x)
  }).set_index('Method')
min_df


I am working on the file "2_cargos_contrata.ipynb".
The first task is:
En el caso de la fecha de término, observamos que la fecha de término contiene el string "Indefinido", y en ambos campos no hay valores nulos. Reemplazaremos Indefinido por nulo.
Can you write Python code for it?

# Reemplazo de indefinido por nulo
fecha_termino = df['Fecha de término'].replace('Indefinido',np.nan)


I am working on the file "2_cargos_contrata.ipynb".
The first task is:
Examinemos los casos anómalos
Can you write Python code for it?

s = 'select servicio,count(*) as nro from df where `Grado EUS` like "Reg%" group by servicio'
sqldf(s)


I am working on the file "2_cargos_contrata.ipynb".
The first task is:
Hay varias correcciones que hacer:

Sacar el símbolo de grado (º)
Eliminar la palabra EUS
Examinar aquellos registros en que aparece una región
Can you write Python code for it?

# Limpieza de símbolos
grados = df['Grado EUS']
grados = grados.str.replace('°','')
grados = grados.str.replace('º','')
grados = grados.str.replace(' EUS','')
grados = grados.str.replace('1C','1')

print(grados.unique().tolist())


I am working on the file "2_cargos_contrata.ipynb".
The first task is:
Limpieza de variables fecha de inicio y término
Can you write Python code for it?

s = 'select distinct `Fecha de inicio` from df'
print(sqldf(s)['Fecha de inicio'].tolist())


I am working on the file "2_cargos_contrata.ipynb".
The first task is:
No aparecen más problemas.
Limpieza de variable Cargo
Can you write Python code for it?

# Primero veamos la lista de cargos con mayor frecuencia de aparición, ej. con frecuencia > 50
q  = "SELECT Cargo,count(*) as Nro FROM df GROUP BY Cargo HAVING Nro>50 ORDER BY 2 desc"
sqldf(q)


I am working on the file "2_cargos_contrata.ipynb".
The first task is:
Nos encontramos con que los casos corresponden a la misma institución (qu.e además tiene el nombre malo). Revisando la página web, podemos ver que el problema es del origen:

Por lo que borraremos estos registros en el merge final
Can you write Python code for it?

# Pasamos los cargos a una variable para limpiar
cargos = df['Cargo'].tolist()

# Para usar la función "clean_text" usaremos además limpieza de conectores gramaticales de la lengua española
stop_words = stopwords.words('spanish')
palabras_a_borrar = []
puntuaciones = string.punctuation

cargos = pd.Series([clean_text(s) for s in cargos])

# Muestra para ver como quedó
cargos[0:10].to_frame(name='cargo')

# Veamos una lista general
df_cargos = cargos.to_frame(name='cargo')
q  = "SELECT cargo,count(*) as nro FROM df_cargos GROUP BY cargo ORDER BY 2 desc"
sqldf(q)


I am working on the file "2_cargos_contrata.ipynb".
The first task is:
Observamos que todos pertencen al Servicio de Evaluación Ambiental. Si miramos la fuente, podemos ver que efectivamente no hay referencias del significado de los prefijos mostrados, por lo que se eliminarán.
Can you write Python code for it?

# No hay stop_words a borrar. Normalmente se usaría stop_words = stopwords.words('spanish')
stop_words = []

# Borramos abreviaciones sin significado
palabras_a_borrar = ['d.','g.','h.','j.']

# Normalmente se usa puntuaciones = string.punctuation
puntuaciones = []

def clean_text(s):

    # 1. Pasar todo a minúsculas y separar en arreglo de palabras
    ws = s.lower().split()

    # 2. Eliminar espaciones innecesarios, junto con conectores gramaticales'''
    ws = [w.strip() for w in ws if w not in stop_words]

    # 3. Remover puntuación
    ws = [w for w in ws if w not in puntuaciones]

    # 4.
    ws = [w for w in ws if w not in palabras_a_borrar]
    return " ".join(ws)

estamentos = df['Estamento'].tolist()

estamentos = pd.Series([clean_text(s) for s in estamentos])

# Uniformemos valores con un diccionario y reemplazamos
d = {
    'técnico': 'tecnico',
    'fiscalizadores': 'fiscalizador',
    'administrativos': 'administrativo',
    'profesionales': 'profesional',
    'tco no profes': 'tecnico',
    'no aplica': 'otro',
    'auxiliares': 'auxiliar',
    'técnicos': 'tecnico'
}
estamentos.replace(d,inplace=True)

estamentos.sort_values().value_counts()


I am working on the file "2_cargos_contrata.ipynb".
The first task is:
Podemos observar que hay fechas metidas entre medio. Veamos los casos:
Can you write Python code for it?

s = 'select servicio,count(*) as nro from df where Cargo like "%/2016" group by Cargo'
sqldf(s)


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
1.2  Cutting our time series into sequences
Remember, our time series is a sequence of numbers that we can represent in general mathematically as
$$s_{0},s_{1},s_{2},...,s_{P}$$
where $s_{p}$ is the numerical value of the time series at time period $p$ and where $P$ is the total length of the series.  In order to apply our RNN we treat the time series prediction problem as a regression problem, and so need to use a sliding window to construct a set of associated input/output pairs to regress on.  This process is animated in the gif below.

For example - using a window of size T = 5 (as illustrated in the gif above) we produce a set of input/output pairs like the one shown in the table below
$$\begin{array}{c|c}
\text{Input} & \text{Output}\
\hline \color{CornflowerBlue} {\langle s_{1},s_{2},s_{3},s_{4},s_{5}\rangle} & \color{Goldenrod}{ s_{6}} \
\ \color{CornflowerBlue} {\langle s_{2},s_{3},s_{4},s_{5},s_{6} \rangle } & \color{Goldenrod} {s_{7} } \
\color{CornflowerBlue}  {\vdots} & \color{Goldenrod} {\vdots}\
\color{CornflowerBlue} { \langle s_{P-5},s_{P-4},s_{P-3},s_{P-2},s_{P-1} \rangle } & \color{Goldenrod} {s_{P}}
\end{array}$$
Notice here that each input is a sequence (or vector) of length 4 (and in general has length equal to the window size T) while each corresponding output is a scalar value.  Notice also how given a time series of length P and window size T = 5 as shown above, we created P - 5  input/output pairs.  More generally, for a window size T we create P - T such pairs.
Now its time for you to window the input time series as described above!

TODO: Implement the function called window_transform_series in my_answers.py so that it runs a sliding window along the input series and creates associated input/output pairs.    Note that this function should input a) the series and b) the window length, and return the input/output subsequences.  Make sure to format returned input/output as generally shown...
Can you write Python code for it?


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
1.3  Splitting into training and testing sets
In order to perform proper testing on our dataset we will lop off the last 1/3 of it for validation (or testing).  This is that once we train our model we have something to test it on (like any regression problem!).  This splitting into training/testing sets is done in the cell below.
Note how here we are not splitting the dataset randomly as one typically would do when validating a regression model.  This is because our input/output pairs are related temporally.   We don't want to validate our model by training on a random subset of the series and then testing on another random subset, as this simulates the scenario that we receive new points within the timeframe of our training set.
We want to train on one solid chunk of the series (in our case, the first full 2/3 of it), and validate on a later chunk (the last 1/3) as this simulates how we would predict future values of a time series.
Can you write Python code for it?

# split our dataset into training / testing sets
train_test_split = int(np.ceil(2*len(y)/float(3)))   # set the split point

# partition the training set
X_train = X[:train_test_split,:]
y_train = y[:train_test_split]

# keep the last chunk for testing
X_test = X[train_test_split:,:]
y_test = y[train_test_split:]

# NOTE: to use keras's RNN LSTM module our input must be reshaped to [samples, window size, stepsize]
X_train = np.asarray(np.reshape(X_train, (X_train.shape[0], window_size, 1)))
X_test = np.asarray(np.reshape(X_test, (X_test.shape[0], window_size, 1)))


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
1.5  Checking model performance
With your model fit we can now make predictions on both our training and testing sets.
Can you write Python code for it?

# generate predictions for training
train_predict = model.predict(X_train)
test_predict = model.predict(X_test)


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
2.3  Cutting data into input/output pairs
Now that we have our text all cleaned up, how can we use it to train a model to generate sentences automatically?  First we need to train a machine learning model - and in order to do that we need a set of input/output pairs for a model to train on.  How can we create a set of input/output pairs from our text to train on?
Remember in part 1 of this notebook how we used a sliding window to extract input/output pairs from a time series?  We do the same thing here!  We slide a window of length $T$ along our giant text corpus - everything in the window becomes one input while the character following becomes its corresponding output.  This process of extracting input/output pairs is illustrated in the gif below on a small example text using a window size of T = 5.
<img src="images/text_windowing_training.gif" width=400 height=400/>
Notice one aspect of the sliding window in this gif that does not mirror the analaogous gif for time series shown in part 1 of the notebook - we do not need to slide the window along one character at a time but can move by a fixed step size $M$ greater than 1 (in the gif indeed $M = 1$).  This is done with large input texts (like ours which has over 500,000 characters!) when sliding the window along one character at a time we would create far too many input/output pairs to be able to reasonably compute with.
More formally lets denote our text corpus - which is one long string of characters - as follows
$$s_{0},s_{1},s_{2},...,s_{P}$$
where $P$ is the length of the text (again for our text $P \approx 500,000!$).  Sliding a window of size T = 5 with a step length of M = 1 (these are the parameters shown in the gif above) over this sequence produces the following list of input/output pairs
$$\begin{array}{c|c}
\text{Input} & \text{Output}\
\hline \color{CornflowerBlue} {\langle s_{1},s_{2},s_{3},s_{4},s_{5}\rangle} & \color{Goldenrod}{ s_{6}} \
\ \color{CornflowerBlue} {\langle s_{2},s_{3},s_{4},s_{5},s_{6} \rangle } & \color{Goldenrod} {s_{7} }...
Can you write Python code for it?

### TODO: implement window_transform_series in my_answers.py
from my_answers import window_transform_series


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
2.7  Training our RNN model for text generation
With our RNN setup we can now train it!  Lets begin by trying it out on a small subset of the larger version.  In the next cell we take the first 10,000 input/output pairs from our training database to learn on.
Can you write Python code for it?

# a small subset of our input/output pairs
Xsmall = X[:10000,:,:]
ysmall = y[:10000,:]


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:

1.4  Build and run an RNN regression model
Having created input/output pairs out of our time series and cut this into training/testing sets, we can now begin setting up our RNN.  We use Keras to quickly build a two hidden layer RNN of the following specifications

layer 1 uses an LSTM module with 5 hidden units (note here the input_shape = (window_size,1))
layer 2 uses a fully connected module with one unit
the 'mean_squared_error' loss should be used (remember: we are performing regression here)

This can be constructed using just a few lines - see e.g., the general Keras documentation and the LTSM documentation in particular for examples of how to quickly use Keras to build neural network models.  Make sure you are initializing your optimizer given the keras-recommended approach for RNNs
(given in the cell below).  (remember to copy your completed function into the script my_answers.py function titled build_part1_RNN before submitting your project)
Can you write Python code for it?

import timeit
# graph the history of model.fit
def show_history_graph(history):
    # summarize history for loss
    plt.plot(history.history['loss'])
    plt.title('model loss')
    plt.ylabel('loss')
    plt.xlabel('epoch')
    plt.legend(['train'], loc='upper left')
    plt.show()

class EpochTimer(keras.callbacks.Callback):
    train_start = 0
    train_end = 0
    epoch_start = 0
    epoch_end = 0

    def get_time(self):
        return timeit.default_timer()

    def on_train_begin(self, logs={}):
        self.train_start = self.get_time()

    def on_train_end(self, logs={}):
        self.train_end = self.get_time()
        print('Training took {} seconds'.format(self.train_end - self.train_start))

    def on_epoch_begin(self, epoch, logs={}):
        self.epoch_start = self.get_time()

    def on_epoch_end(self, epoch, logs={}):
        self.epoch_end = self.get_time()
        print('Epoch {} took {} seconds'.format(epoch, self.epoch_end - self.epoch_start))

### TODO: create required RNN model
# import keras network libraries
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
import keras

# given - fix random seed - so we can all reproduce the same results on our default time series
np.random.seed(0)

# TODO: implement build_part1_RNN in my_answers.py
from my_answers import build_part1_RNN
model = build_part1_RNN(window_size)

# build model using keras documentation recommended optimizer initialization
optimizer = keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)

# compile the model
model.compile(loss='mean_squared_error', optimizer=optimizer)


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:

2.6 Setting up our RNN
With our dataset loaded and the input/output pairs extracted / transformed we can now begin setting up our RNN for training.  Again we will use Keras to quickly build a single hidden layer RNN - where our hidden layer consists of LTSM modules.
Time to get to work: build a 3 layer RNN model of the following specification

layer 1 should be an LSTM module with 200 hidden units --> note this should have input_shape = (window_size,len(chars)) where len(chars) = number of unique characters in your cleaned text
layer 2 should be a linear module, fully connected, with len(chars) hidden units --> where len(chars) = number of unique characters in your cleaned text
layer 3 should be a softmax activation ( since we are solving a multiclass classification)
Use the categorical_crossentropy loss

This network can be constructed using just a few lines - as with the RNN network you made in part 1 of this notebook.  See e.g., the general Keras documentation and the LTSM documentation in particular for examples of how to quickly use Keras to build neural network models.
Can you write Python code for it?

### necessary functions from the keras library
from keras.models import Sequential
from keras.layers import Dense, Activation, LSTM
from keras.optimizers import RMSprop
from keras.utils.data_utils import get_file
import keras
import random

# TODO implement build_part2_RNN in my_answers.py
from my_answers import build_part2_RNN

model = build_part2_RNN(window_size, len(chars))

# initialize optimizer
optimizer = keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)

# compile model --> make sure initialized optimizer and callbacks - as defined above - are used
model.compile(loss='categorical_crossentropy', optimizer=optimizer)
model.summary()


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Again - you can check that your completed window_transform_series function works correctly by trying it on the odd_nums sequence - you should get the above output.
Can you write Python code for it?

### TODO: implement the function window_transform_series in the file my_answers.py
from my_answers import window_transform_series


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
How do we make a given number of predictions (characters) based on this fitted model?
First we predict the next character after following any chunk of characters in the text of length equal to our chosen window size.  Then we remove the first character in our input sequence and tack our prediction onto the end.  This gives us a slightly changed sequence of inputs that still has length equal to the size of our window.  We then feed in this updated input sequence into the model to predict the another character.  Together then we have two predicted characters following our original input sequence.  Repeating this process N times gives us N predicted characters.
In the next Python cell we provide you with a completed function that does just this - it makes predictions when given a) a trained RNN model, b) a subset of (window_size) characters from the text, and c) a number of characters to predict (to follow our input subset).
Can you write Python code for it?

# function that uses trained model to predict a desired number of future characters
def predict_next_chars(model, input_chars, num_to_predict):
    # create output
    predicted_chars = ''
    for i in range(num_to_predict):
        # convert this round's predicted characters to numerical input
        x_test = np.zeros((1, window_size, len(chars)))
        for t, char in enumerate(input_chars):
            x_test[0, t, chars_to_indices[char]] = 1.

        # make this round's prediction
        test_predict = model.predict(x_test, verbose=0)[0]

        # translate numerical prediction back to characters
        r = np.argmax(test_predict) # predict class of each test input
        d = indices_to_chars[r]

        # update predicted_chars and input
        predicted_chars += d
        input_chars += d
        input_chars = input_chars[1:]
    return predicted_chars


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
In the next cell we compute training and testing errors using our trained model - you should be able to achieve at least
training_error < 0.02
and
testing_error < 0.02
with your fully trained model.
If either or both of your accuracies are larger than 0.02 re-train your model - increasing the number of epochs you take (a maximum of around 1,000 should do the job) and/or adjusting your batch_size.
Can you write Python code for it?

# print out training and testing errors
training_error = model.evaluate(X_train, y_train, verbose=0)
print('training error = ' + str(training_error))

testing_error = model.evaluate(X_test, y_test, verbose=0)
print('testing error = ' + str(testing_error))


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Lets print out a few input/output pairs to verify that we have made the right sort of stuff!
Can you write Python code for it?

# print out a few of the input/output pairs to verify that we've made the right kind of stuff to learn from
print('input = ' + inputs[2])
print('output = ' + outputs[2])
print('--------------')
print('input = ' + inputs[100])
print('output = ' + outputs[100])


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Lets see how the first 1000 characters of our text looks now!
Can you write Python code for it?

### print out the first 1000 characters of the raw text to get a sense of what we need to throw out
text[:1000]


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Lets take a quick look at the (normalized) time series we'll be performing predictions on.
Can you write Python code for it?

# lets take a look at our time series
plt.plot(dataset)
plt.xlabel('time period')
plt.ylabel('normalized series value')


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Looks good!
2.4  Wait, what kind of problem is text generation again?
In part 1 of this notebook we used the same pre-processing technique - the sliding window - to produce a set of training input/output pairs to tackle the problem of time series prediction by treating the problem as one of regression.  So what sort of problem do we have here now, with text generation?  Well, the time series prediction was a regression problem because the output (one value of the time series) was a continuous value.  Here - for character-by-character text generation - each output is a single character.  This isn't a continuous value - but a distinct class - therefore character-by-character text generation is a classification problem.
How many classes are there in the data?  Well, the number of classes is equal to the number of unique characters we have to predict!  How many of those were there in our dataset again?  Lets print out the value again.
Can you write Python code for it?

# print out the number of unique characters in the dataset
chars = sorted(list(set(text)))
print("this corpus has " +  str(len(chars)) + " unique characters")
print('and these characters are ')
print(chars)


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Next, lets examine a bit of the raw text.  Because we are interested in creating sentences of English words automatically by building up each word character-by-character, we only want to train on valid English words.  In other words - we need to remove all of the other characters that are not part of English words.
Can you write Python code for it?

### print out the first 1000 characters of the raw text to get a sense of what we need to throw out
text[:2000]


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Now lets fit our model!
Can you write Python code for it?

# train the model
epochtimer = EpochTimer()
epochs = 40
hist = model.fit(Xsmall, ysmall, batch_size=500, epochs=epochs, verbose=1, callbacks=[epochtimer])
show_history_graph(hist)

# save weights
model.save_weights('model_weights/best_RNN_small_textdata_weights.hdf5')


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Now run the one-hot encoding function by activating the cell below and transform our input/output pairs!
Can you write Python code for it?

# use your function
window_size = 100
step_size = 5
X, y = encode_io_pairs(text, window_size, step_size)


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Now that we have thrown out a good number of non-English characters/character sequences lets print out some statistics about the dataset - including number of total characters and number of unique characters.
Can you write Python code for it?

# count the number of unique characters in the text
chars = sorted(list(set(text)))

# print some of the text, as well as statistics
print ("this corpus has " +  str(len(text)) + " total number of characters")
print ("this corpus has " +  str(len(chars)) + " unique characters")


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Now we can transform our input/output pairs - consisting of characters - to equivalent input/output pairs made up of one-hot encoded vectors.  In the next cell we provide a function for doing just this: it takes in the raw character input/outputs and returns their numerical versions.  In particular the numerical input is given as $\bf{X}$, and numerical output is given as the $\bf{y}$
Can you write Python code for it?

# transform character-based input/output into equivalent numerical versions
def encode_io_pairs(text, window_size, step_size):
    # number of unique chars
    chars = sorted(list(set(text)))
    num_chars = len(chars)

    # cut up text into character input/output pairs
    inputs, outputs = window_transform_text(text, window_size, step_size)

    # create empty vessels for one-hot encoded input/output
    X = np.zeros((len(inputs), window_size, num_chars), dtype=np.bool)
    y = np.zeros((len(inputs), num_chars), dtype=np.bool)

    # loop over inputs/outputs and tranform and store in X/y
    for i, sentence in enumerate(inputs):
        for t, char in enumerate(sentence):
            X[i, t, chars_to_indices[char]] = 1
        y[i, chars_to_indices[outputs[i]]] = 1

    return X, y


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Rockin' - so we have a multi-class classification problem on our hands!
2.5  One-hot encoding characters
There's just one last issue we have to deal with before tackle: machine learning algorithm deal with numerical data and all of our input/output pairs are characters.  So we just need to transform our characters into equivalent numerical values.  The most common way of doing this is via a 'one-hot encoding' scheme.  Here's how it works.
We transform each character in our inputs/outputs into a vector with length equal to the number of unique characters in our text.  This vector is all zeros except one location where we place a 1 - and this location is unique to each character type.  e.g., we transform 'a', 'b', and 'c' as follows
$$a\longleftarrow\left[\begin{array}{c}
1\
0\
0\
\vdots\
0\
0
\end{array}\right]\,\,\,\,\,\,\,b\longleftarrow\left[\begin{array}{c}
0\
1\
0\
\vdots\
0\
0
\end{array}\right]\,\,\,\,\,c\longleftarrow\left[\begin{array}{c}
0\
0\
1\
\vdots\
0\
0
\end{array}\right]\cdots$$
where each vector has 32 entries (or in general: number of entries = number of unique characters in text).
The first practical step towards doing this one-hot encoding is to form a dictionary mapping each unique character to a unique integer, and one dictionary to do the reverse mapping.  We can then use these dictionaries to quickly make our one-hot encodings, as well as re-translate (from integers to characters) the results of our trained RNN classification model.
Can you write Python code for it?

# this dictionary is a function mapping each unique character to a unique integer
chars_to_indices = dict((c, i) for i, c in enumerate(chars))  # map each unique character to unique integer

# this dictionary is a function mapping each unique integer back to a unique character
indices_to_chars = dict((i, c) for i, c in enumerate(chars))  # map each unique integer back to unique character


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
With our function complete we can now use it to produce input/output pairs!  We employ the function in the next cell, where the window_size = 100 and step_size = 5.
Can you write Python code for it?

# run your text window-ing function
window_size = 100
step_size = 5
inputs, outputs = window_transform_text(text,window_size,step_size)


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
With this recording devices we can now more safely perform experiments on larger portions of the text.  In the next cell we will use the first 100,000 input/output pairs to train our RNN model.
First we fit our model to the dataset, then generate text using the trained model in precisely the same generation method applied before on the small dataset.
Note: your generated words should be - by and large - more realistic than with the small dataset, but you won't be able to generate perfect English sentences even with this amount of data.  A rule of thumb: your model is working well if you generate sentences that largely contain real English words.
Can you write Python code for it?

# a small subset of our input/output pairs
Xlarge = X[:100000,:,:]
ylarge = y[:100000,:]

# TODO: fit to our larger dataset
epochtimer = EpochTimer()
epochs = 30

hist = model.fit(Xlarge, ylarge, batch_size=500, epochs=epochs, verbose=1, callbacks=[epochtimer])
show_history_graph(hist)

# save weights
model.save_weights('model_weights/best_RNN_large_textdata_weights.hdf5')

# TODO: choose an input sequence and use the prediction function in the previous Python cell to predict 100 characters following it
# get an appropriately sized chunk of characters from the text
start_inds = [1000, 2000, 3000, 4000, 5000]
window_size = 100
# save output
f = open('text_gen_output/RNN_large_textdata_output.txt', 'w')  # create an output file to write too

# load weights
model.load_weights('model_weights/best_RNN_large_textdata_weights.hdf5')
for s in start_inds:
    start_index = s
    input_chars = text[start_index: start_index + window_size]

    # use the prediction function
    predict_input = predict_next_chars(model, input_chars, num_to_predict = 100)

    # print out input characters
    line = '-------------------' + '\n'
    print(line)
    f.write(line)

    input_line = 'input chars = ' + '\n' +  input_chars + '"' + '\n'
    print(input_line)
    f.write(input_line)

    # print out predicted characters
    predict_line = 'predicted chars = ' + '\n' +  predict_input + '"' + '\n'
    print(predict_line)
    f.write(predict_line)
f.close()

# TODO: fit to our larger dataset
epochtimer = EpochTimer()
epochs = 30

hist = model.fit(Xlarge, ylarge, batch_size=500, epochs=epochs, verbose=1, callbacks=[epochtimer])
show_history_graph(hist)

# save weights
model.save_weights('model_weights/best_RNN_large_textdata_weights_again.hdf5')

# TODO: choose an input sequence and use the prediction function in the previous Python cell to predict 100 characters following it
# get an appropriately sized chunk of characters from the text
start_inds = [1000, 2000, 3000, 4000, 5000]
window_size = 100
# save output
f =...


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
With your chosen characters removed print out the first few hundred lines again just to double check that everything looks good.
Can you write Python code for it?

### print out the first 2000 characters of the raw text to get a sense of what we need to throw out
text[:2000]


I am working on the file "2_deep_learning/2_rnn_stock_sherlock/RNN_project.ipynb".
The first task is:
Wow - there's a lot of junk here (i.e., weird uncommon character combinations - as this first character chunk contains the title and author page, as well as table of contents)!  To keep things simple, we want to train our RNN on a large chunk of more typical English sentences - we don't want it to start thinking non-english words or strange characters are valid! - so lets clean up the data a bit.
First, since the dataset is so large and the first few hundred characters contain a lot of junk, lets cut it out.  Lets also find-and-replace those newline tags with empty spaces.
Can you write Python code for it?

### find and replace '\n' and '\r' symbols - replacing them
text = text[1302:]
text = text.replace('\n',' ')    # replacing '\n' with '' simply removes the sequence
text = text.replace('\r',' ')


I am working on the file "2_fullyconnected.ipynb".
The first task is:
First reload the data we generated in 1_notmist.ipynb.
Can you write Python code for it?

pickle_file = 'notMNIST.pickle'

with open(pickle_file, 'rb') as f:
  save = pickle.load(f)
  train_dataset = save['train_dataset']
  train_labels = save['train_labels']
  valid_dataset = save['valid_dataset']
  valid_labels = save['valid_labels']
  test_dataset = save['test_dataset']
  test_labels = save['test_labels']
  del save  # hint to help gc free up memory
  print('Training set', train_dataset.shape, train_labels.shape)
  print('Validation set', valid_dataset.shape, valid_labels.shape)
  print('Test set', test_dataset.shape, test_labels.shape)


I am working on the file "2_fullyconnected.ipynb".
The first task is:
First reload the data we generated in 1_notmnist.ipynb.
Can you write Python code for it?


I am working on the file "2_fullyconnected.ipynb".
The first task is:
Let's now switch to stochastic gradient descent training instead, which is much faster.
The graph will be similar, except that instead of holding all the training data into a constant node, we create a Placeholder node which will be fed actual data at every call of sesion.run().
Can you write Python code for it?

batch_size = 128

graph = tf.Graph()
with graph.as_default():

  # Input data. For the training data, we use a placeholder that will be fed
  # at run time with a training minibatch.
  tf_train_dataset = tf.placeholder(tf.float32,
                                    shape=(batch_size, image_size * image_size))
  tf_train_labels = tf.placeholder(tf.float32, shape=(batch_size, num_labels))
  tf_valid_dataset = tf.constant(valid_dataset)
  tf_test_dataset = tf.constant(test_dataset)

  # Variables.
  weights = tf.Variable(
    tf.truncated_normal([image_size * image_size, num_labels]))
  biases = tf.Variable(tf.zeros([num_labels]))

  # Training computation.
  logits = tf.matmul(tf_train_dataset, weights) + biases
  loss = tf.reduce_mean(
    tf.nn.softmax_cross_entropy_with_logits(logits, tf_train_labels))

  # Optimizer.
  optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss)

  # Predictions for the training, validation, and test data.
  train_prediction = tf.nn.softmax(logits)
  valid_prediction = tf.nn.softmax(
    tf.matmul(tf_valid_dataset, weights) + biases)
  test_prediction = tf.nn.softmax(tf.matmul(tf_test_dataset, weights) + biases)


I am working on the file "2_fullyconnected.ipynb".
The first task is:
Let's now switch to stochastic gradient descent training instead, which is much faster.
The graph will be similar, except that instead of holding all the training data into a constant node, we create a Placeholder node which will be fed actual data at every call of session.run().
Can you write Python code for it?


I am working on the file "2_fullyconnected.ipynb".
The first task is:
Let's run it:
Can you write Python code for it?

num_steps = 3001

with tf.Session(graph=graph) as session:
  tf.initialize_all_variables().run()
  print("Initialized")
  for step in range(num_steps):
    # Pick an offset within the training data, which has been randomized.
    # Note: we could use better randomization across epochs.
    offset = (step * batch_size) % (train_labels.shape[0] - batch_size)
    # Generate a minibatch.
    batch_data = train_dataset[offset:(offset + batch_size), :]
    batch_labels = train_labels[offset:(offset + batch_size), :]
    # Prepare a dictionary telling the session where to feed the minibatch.
    # The key of the dictionary is the placeholder node of the graph to be fed,
    # and the value is the numpy array to feed to it.
    feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels}
    _, l, predictions = session.run(
      [optimizer, loss, train_prediction], feed_dict=feed_dict)
    if (step % 500 == 0):
      print("Minibatch loss at step %d: %f" % (step, l))
      print("Minibatch accuracy: %.1f%%" % accuracy(predictions, batch_labels))
      print("Validation accuracy: %.1f%%" % accuracy(
        valid_prediction.eval(), valid_labels))
  print("Test accuracy: %.1f%%" % accuracy(test_prediction.eval(), test_labels))


num_steps = 3001

with tf.Session(graph=graph) as session:
  tf.global_variables_initializer().run()
  print("Initialized")
  for step in range(num_steps):
    # Pick an offset within the training data, which has been randomized.
    # Note: we could use better randomization across epochs.
    offset = (step * batch_size) % (train_labels.shape[0] - batch_size)
    # Generate a minibatch.
    batch_data = train_dataset[offset:(offset + batch_size), :]
    batch_labels = train_labels[offset:(offset + batch_size), :]
    # Prepare a dictionary telling the session where to feed the minibatch.
    # The key of the dictionary is the placeholder node of the graph to be fed,
    # and the value is the numpy array to feed to it.
    feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels}
    _, l, predictions = session.run(
      [optimizer, loss, train_prediction], feed_dict=feed_dict)
    if (step % 500 == 0):
      print("Minibatch loss at step %d: %f" % (step, l))
      print("Minibatch accuracy: %.1f%%" % accuracy(predictions, batch_labels))
      print("Validation accuracy: %.1f%%" % accuracy(
        valid_prediction.eval(), valid_labels))
  print("Test accuracy: %.1f%%" % accuracy(test_prediction.eval(), test_labels))


I am working on the file "2_fullyconnected.ipynb".
The first task is:
Let's run this computation and iterate:
Can you write Python code for it?

num_steps = 801

def accuracy(predictions, labels):
  return (100.0 * np.sum(np.argmax(predictions, 1) == np.argmax(labels, 1))
          / predictions.shape[0])

with tf.Session(graph=graph) as session:
  # This is a one-time operation which ensures the parameters get initialized as
  # we described in the graph: random weights for the matrix, zeros for the
  # biases.
  tf.initialize_all_variables().run()
  print('Initialized')
  for step in range(num_steps):
    # Run the computations. We tell .run() that we want to run the optimizer,
    # and get the loss value and the training predictions returned as numpy
    # arrays.
    _, l, predictions = session.run([optimizer, loss, train_prediction])
    if (step % 100 == 0):
      print('Loss at step %d: %f' % (step, l))
      print('Training accuracy: %.1f%%' % accuracy(
        predictions, train_labels[:train_subset, :]))
      # Calling .eval() on valid_prediction is basically like calling run(), but
      # just to get that one numpy array. Note that it recomputes all its graph
      # dependencies.
      print('Validation accuracy: %.1f%%' % accuracy(
        valid_prediction.eval(), valid_labels))
  print('Test accuracy: %.1f%%' % accuracy(test_prediction.eval(), test_labels))


num_steps = 801

def accuracy(predictions, labels):
  return (100.0 * np.sum(np.argmax(predictions, 1) == np.argmax(labels, 1))
          / predictions.shape[0])

with tf.Session(graph=graph) as session:
  # This is a one-time operation which ensures the parameters get initialized as
  # we described in the graph: random weights for the matrix, zeros for the
  # biases.
  tf.global_variables_initializer().run()
  print('Initialized')
  for step in range(num_steps):
    # Run the computations. We tell .run() that we want to run the optimizer,
    # and get the loss value and the training predictions returned as numpy
    # arrays.
    _, l, predictions = session.run([optimizer, loss, train_prediction])
    if (step % 100 == 0):
      print('Loss at step %d: %f' % (step, l))
      print('Training accuracy: %.1f%%' % accuracy(
        predictions, train_labels[:train_subset, :]))
      # Calling .eval() on valid_prediction is basically like calling run(), but
      # just to get that one numpy array. Note that it recomputes all its graph
      # dependencies.
      print('Validation accuracy: %.1f%%' % accuracy(
        valid_prediction.eval(), valid_labels))
  print('Test accuracy: %.1f%%' % accuracy(test_prediction.eval(), test_labels))


I am working on the file "2_fullyconnected.ipynb".
The first task is:
Problem
Turn the logistic regression example with SGD into a 1-hidden layer neural network with rectified linear units (nn.relu()) and 1024 hidden nodes. This model should improve your validation / test accuracy.

Remember:
TensorFlow works like this:
* First you describe the computation that you want to see performed: what the inputs, the variables, and the operations look like. These get created as nodes over a computation graph. This description is all contained within the block below:
  with graph.as_default():
      ...
Can you write Python code for it?

H = 1024

# accuracy() defined above
# below is an adapted copy of above SGD case with a hidden layer added:

graph = tf.Graph()
with graph.as_default():

    # Input data. For the training data, we use a placeholder that will be fed
    # at run time with a training minibatch.
    tf_train_dataset = tf.placeholder(tf.float32,
                                    shape=(batch_size, image_size * image_size))
    tf_train_labels = tf.placeholder(tf.float32, shape=(batch_size, num_labels))
    tf_valid_dataset = tf.constant(valid_dataset)
    tf_test_dataset = tf.constant(test_dataset)

    # Variables.
    weights1 = tf.Variable(tf.truncated_normal([image_size * image_size, H], stddev=0.1))
    weights2 = tf.Variable(tf.truncated_normal([H, num_labels], stddev=0.1))
    biases1 = tf.Variable(tf.constant(0.1, shape=[H]))
    biases2 = tf.Variable(tf.constant(0.1, shape=[num_labels]))

    # Training computation.
    hidden = tf.nn.relu(tf.matmul(tf_train_dataset, weights1) + biases1)
    logits = tf.matmul(hidden, weights2) + biases2
    loss = tf.reduce_mean(
      tf.nn.softmax_cross_entropy_with_logits(logits, tf_train_labels))

    # Optimizer.Altering step size can lead to NaNs in matrices
    optimizer = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

    # Predictions for the training, validation, and test data.
    train_prediction = tf.nn.softmax(logits)

    valid_logits = tf.matmul(tf.nn.relu(tf.matmul(tf_valid_dataset, weights1) + biases1), weights2) + biases2
    test_logits = tf.matmul(tf.nn.relu(tf.matmul(tf_test_dataset, weights1) + biases1), weights2) + biases2

    valid_prediction = tf.nn.softmax(valid_logits)
    test_prediction = tf.nn.softmax(test_logits)


I am working on the file "2_fullyconnected.ipynb".
The first task is:
Problem
Turn the logistic regression example with SGD into a 1-hidden layer neural network with rectified linear units (nn.relu()) and 1024 hidden nodes. This model should improve your validation / test accuracy.
Can you write Python code for it?

batch_size = 128
num_hidden_nodes = 1024

graph = tf.Graph()
with graph.as_default():

  # Input data. For the training data, we use a placeholder that will be fed
  # at run time with a training minibatch.
  tf_train_dataset = tf.placeholder(tf.float32,
                                    shape=(batch_size, image_size * image_size))
  tf_train_labels = tf.placeholder(tf.float32, shape=(batch_size, num_labels))
  tf_valid_dataset = tf.constant(valid_dataset)
  tf_test_dataset = tf.constant(test_dataset)

  # Variables.
  weights1 = tf.Variable(
    tf.truncated_normal([image_size * image_size, num_hidden_nodes]))
  biases1 = tf.Variable(tf.zeros([num_hidden_nodes]))
  weights2 = tf.Variable(
    tf.truncated_normal([num_hidden_nodes, num_labels]))
  biases2 = tf.Variable(tf.zeros([num_labels]))

  # Training computation.
  lay1_train = tf.nn.relu(tf.matmul(tf_train_dataset, weights1) + biases1)
  logits = tf.matmul(lay1_train, weights2) + biases2
  loss = tf.reduce_mean(
    tf.nn.softmax_cross_entropy_with_logits(logits, tf_train_labels))

  # Optimizer.
  optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss)

  # Predictions for the training, validation, and test data.
  train_prediction = tf.nn.softmax(logits)
  lay1_valid = tf.nn.relu(tf.matmul(tf_valid_dataset, weights1) + biases1)
  valid_prediction = tf.nn.softmax(tf.matmul(lay1_valid, weights2) + biases2)
  lay1_test = tf.nn.relu(tf.matmul(tf_test_dataset, weights1) + biases1)
  test_prediction = tf.nn.softmax(tf.matmul(lay1_test, weights2) + biases2)

num_steps = 3001

with tf.Session(graph=graph) as session:
  tf.initialize_all_variables().run()
  print("Initialized")
  for step in range(num_steps):
    # Pick an offset within the training data, which has been randomized.
    # Note: we could use better randomization across epochs.
    offset = (step * batch_size) % (train_labels.shape[0] - batch_size)
    # Generate a minibatch.
    batch_data = train_dataset[offset:(offset + batch_size), :]
    batch_labels =...


I am working on the file "2_fullyconnected.ipynb".
The first task is:
Reformat into a shape that's more adapted to the models we're going to train:
- data as a flat matrix,
- labels as float 1-hot encodings.
Can you write Python code for it?

image_size = 28
num_labels = 10

def reformat(dataset, labels):
  dataset = dataset.reshape((-1, image_size * image_size)).astype(np.float32)
  # Map 0 to [1.0, 0.0, 0.0 ...], 1 to [0.0, 1.0, 0.0 ...]
  labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)
  return dataset, labels
train_dataset, train_labels = reformat(train_dataset, train_labels)
valid_dataset, valid_labels = reformat(valid_dataset, valid_labels)
test_dataset, test_labels = reformat(test_dataset, test_labels)
print('Training set', train_dataset.shape, train_labels.shape)
print('Validation set', valid_dataset.shape, valid_labels.shape)
print('Test set', test_dataset.shape, test_labels.shape)


image_size = 28
num_labels = 10

def reformat(dataset, labels):
  dataset = dataset.reshape((-1, image_size * image_size)).astype(np.float32)
  # Map 0 to [1.0, 0.0, 0.0 ...], 1 to [0.0, 1.0, 0.0 ...]
  labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)
  return dataset, labels
train_dataset, train_labels = reformat(train_dataset, train_labels)
valid_dataset, valid_labels = reformat(valid_dataset, valid_labels)
test_dataset, test_labels = reformat(test_dataset, test_labels)
print 'Training set', train_dataset.shape, train_labels.shape
print 'Validation set', valid_dataset.shape, valid_labels.shape
print 'Test set', test_dataset.shape, test_labels.shape


I am working on the file "2_fullyconnected.ipynb".
The first task is:
Then you can run the operations on this graph as many times as you want by calling session.run(), providing it outputs to fetch from the graph that get returned. This runtime operation is all contained in the block below:
with tf.Session(graph=graph) as session:
      ...
Can you write Python code for it?

# This is a straight copy of corresponding run code from above SGD case:

num_steps = 3001

with tf.Session(graph=graph) as session:
  tf.initialize_all_variables().run()
  print("Initialized")
  for step in range(num_steps):
    # Pick an offset within the training data, which has been randomized.
    # Note: we could use better randomization across epochs.
    offset = (step * batch_size) % (train_labels.shape[0] - batch_size)
    # Generate a minibatch.
    batch_data = train_dataset[offset:(offset + batch_size), :]
    batch_labels = train_labels[offset:(offset + batch_size), :]
    # Prepare a dictionary telling the session where to feed the minibatch.
    # The key of the dictionary is the placeholder node of the graph to be fed,
    # and the value is the numpy array to feed to it.
    feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels}
    _, l, predictions = session.run(
      [optimizer, loss, train_prediction], feed_dict=feed_dict)
    if (step % 500 == 0):
      print("Minibatch loss at step %d: %f" % (step, l))
      print("Minibatch accuracy: %.1f%%" % accuracy(predictions, batch_labels))
      print("Validation accuracy: %.1f%%" % accuracy(
        valid_prediction.eval(), valid_labels))
  print("Test accuracy: %.1f%%" % accuracy(test_prediction.eval(), test_labels))


I am working on the file "2_fullyconnected.ipynb".
The first task is:
We're first going to train a multinomial logistic regression using simple gradient descent.
TensorFlow works like this:
* First you describe the computation that you want to see performed: what the inputs, the variables, and the operations look like. These get created as nodes over a computation graph. This description is all contained within the block below:
  with graph.as_default():
      ...

Then you can run the operations on this graph as many times as you want by calling session.run(), providing it outputs to fetch from the graph that get returned. This runtime operation is all contained in the block below:
with tf.Session(graph=graph) as session:
      ...

Let's load all the data into TensorFlow and build the computation graph corresponding to our training:
Can you write Python code for it?

# With gradient descent training, even this much data is prohibitive.
# Subset the training data for faster turnaround.
train_subset = 10000

graph = tf.Graph()
with graph.as_default():

  # Input data.
  # Load the training, validation and test data into constants that are
  # attached to the graph.
  tf_train_dataset = tf.constant(train_dataset[:train_subset, :])
  tf_train_labels = tf.constant(train_labels[:train_subset])
  tf_valid_dataset = tf.constant(valid_dataset)
  tf_test_dataset = tf.constant(test_dataset)

  # Variables.
  # These are the parameters that we are going to be training. The weight
  # matrix will be initialized using random valued following a (truncated)
  # normal distribution. The biases get initialized to zero.
  weights = tf.Variable(
    tf.truncated_normal([image_size * image_size, num_labels]))
  biases = tf.Variable(tf.zeros([num_labels]))

  # Training computation.
  # We multiply the inputs with the weight matrix, and add biases. We compute
  # the softmax and cross-entropy (it's one operation in TensorFlow, because
  # it's very common, and it can be optimized). We take the average of this
  # cross-entropy across all training examples: that's our loss.
  logits = tf.matmul(tf_train_dataset, weights) + biases
  loss = tf.reduce_mean(
    tf.nn.softmax_cross_entropy_with_logits(logits, tf_train_labels))

  # Optimizer.
  # We are going to find the minimum of this loss using gradient descent.
  optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss)

  # Predictions for the training, validation, and test data.
  # These are not part of training, but merely here so that we can report
  # accuracy figures as we train.
  train_prediction = tf.nn.softmax(logits)
  valid_prediction = tf.nn.softmax(
    tf.matmul(tf_valid_dataset, weights) + biases)
  test_prediction = tf.nn.softmax(tf.matmul(tf_test_dataset, weights) + biases)


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Build the network
For the neural network, you'll build each layer into a function.  Most of the code you've seen has been outside of functions. To test your code more thoroughly, we require that you put each layer in a function.  This allows us to give you better feedback and test for simple mistakes using our unittests before you submit your project.

Note: If you're finding it hard to dedicate enough time for this course each week, we've provided a small shortcut to this part of the project. In the next couple of problems, you'll have the option to use classes from the TensorFlow Layers or TensorFlow Layers (contrib) packages to build each layer, except the layers you build in the "Convolutional and Max Pooling Layer" section.  TF Layers is similar to Keras's and TFLearn's abstraction to layers, so it's easy to pickup.
However, if you would like to get the most out of this course, try to solve all the problems without using anything from the TF Layers packages. You can still use classes from other packages that happen to have the same name as ones you find in TF Layers! For example, instead of using the TF Layers version of the conv2d class, tf.layers.conv2d, you would want to use the TF Neural Network version of conv2d, tf.nn.conv2d.

Let's begin!
Input
The neural network needs to read the image data, one-hot encoded labels, and dropout keep probability. Implement the following functions
* Implement neural_net_image_input
 * Return a TF Placeholder
 * Set the shape using image_shape with batch size set to None.
 * Name the TensorFlow placeholder "x" using the TensorFlow name parameter in the TF Placeholder.
* Implement neural_net_label_input
 * Return a TF Placeholder
 * Set the shape using n_classes with batch size set to None.
 * Name the TensorFlow placeholder "y" using the TensorFlow name parameter in the TF Placeholder.
* Implement neural_net_keep_prob_input
 * Return a TF Placeholder for dropout keep probability.
 * Name the TensorFlow placeholder "keep_prob" using the TensorFlow name parameter in...
Can you write Python code for it?

import tensorflow as tf

def neural_net_image_input(image_shape):
    """
    Return a Tensor for a bach of image input
    : image_shape: Shape of the images
    : return: Tensor for image input.
    """

    return tf.placeholder(tf.float32, shape=(None, image_shape[0], image_shape[1], image_shape[2]), name='x')

def neural_net_label_input(n_classes):
    """
    Return a Tensor for a batch of label input
    : n_classes: Number of classes
    : return: Tensor for label input.
    """

    return tf.placeholder(tf.float32,(None, n_classes), name='y')

def neural_net_keep_prob_input():
    """
    Return a Tensor for keep probability
    : return: Tensor for keep probability.
    """

    return tf.placeholder(tf.float32, name='keep_prob')

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tf.reset_default_graph()
tests.test_nn_image_inputs(neural_net_image_input)
tests.test_nn_label_inputs(neural_net_label_input)
tests.test_nn_keep_prob_inputs(neural_net_keep_prob_input)


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Check Point
This is your first checkpoint.  If you ever decide to come back to this notebook or have to restart the notebook, you can start from here.  The preprocessed data has been saved to disk.
Can you write Python code for it?

"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import pickle
import problem_unittests as tests
import helper

# Load the Preprocessed Validation data
valid_features, valid_labels = pickle.load(open('preprocess_validation.p', mode='rb'))


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Checkpoint
The model has been saved to disk.
Test Model
Test your model against the test dataset.  This will be your final accuracy. You should have an accuracy greater than 50%. If you don't, keep tweaking the model architecture and parameters.
Can you write Python code for it?

"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
%matplotlib inline
%config InlineBackend.figure_format = 'retina'

import tensorflow as tf
import pickle
import helper
import random

# Set batch size if not already set
try:
    if batch_size:
        pass
except NameError:
    batch_size = 64

save_model_path = './image_classification'
n_samples = 4
top_n_predictions = 3

def test_model():
    """
    Test the saved model against the test dataset
    """

    test_features, test_labels = pickle.load(open('preprocess_training.p', mode='rb'))
    loaded_graph = tf.Graph()

    with tf.Session(graph=loaded_graph) as sess:
        # Load model
        loader = tf.train.import_meta_graph(save_model_path + '.meta')
        loader.restore(sess, save_model_path)

        # Get Tensors from loaded model
        loaded_x = loaded_graph.get_tensor_by_name('x:0')
        loaded_y = loaded_graph.get_tensor_by_name('y:0')
        loaded_keep_prob = loaded_graph.get_tensor_by_name('keep_prob:0')
        loaded_logits = loaded_graph.get_tensor_by_name('logits:0')
        loaded_acc = loaded_graph.get_tensor_by_name('accuracy:0')

        # Get accuracy in batches for memory limitations
        test_batch_acc_total = 0
        test_batch_count = 0

        for train_feature_batch, train_label_batch in helper.batch_features_labels(test_features, test_labels, batch_size):
            test_batch_acc_total += sess.run(
                loaded_acc,
                feed_dict={loaded_x: train_feature_batch, loaded_y: train_label_batch, loaded_keep_prob: 1.0})
            test_batch_count += 1

        print('Testing Accuracy: {}\n'.format(test_batch_acc_total/test_batch_count))

        # Print Random Samples
        random_test_features, random_test_labels = tuple(zip(*random.sample(list(zip(test_features, test_labels)), n_samples)))
        random_test_predictions = sess.run(
            tf.nn.top_k(tf.nn.softmax(loaded_logits), top_n_predictions),
            feed_dict={loaded_x: random_test_features, loaded_y:...


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Convolution and Max Pooling Layer
Convolution layers have a lot of success with images. For this code cell, you should implement the function conv2d_maxpool to apply convolution then max pooling:
* Create the weight and bias using conv_ksize, conv_num_outputs and the shape of x_tensor.
* Apply a convolution to x_tensor using weight and conv_strides.
 * We recommend you use same padding, but you're welcome to use any padding.
* Add bias
* Add a nonlinear activation to the convolution.
* Apply Max Pooling using pool_ksize and pool_strides.
 * We recommend you use same padding, but you're welcome to use any padding.
Note: You can't use TensorFlow Layers or TensorFlow Layers (contrib) for this layer, but you can still use TensorFlow's Neural Network package. You may still use the shortcut option for all the other layers.
Can you write Python code for it?

def conv2d_maxpool(x_tensor, conv_num_outputs, conv_ksize, conv_strides, pool_ksize, pool_strides):
    """
    Apply convolution then max pooling to x_tensor
    :param x_tensor: TensorFlow Tensor
    :param conv_num_outputs: Number of outputs for the convolutional layer
    :param conv_ksize: kernal size 2-D Tuple for the convolutional layer
    :param conv_strides: Stride 2-D Tuple for convolution
    :param pool_ksize: kernal size 2-D Tuple for pool
    :param pool_strides: Stride 2-D Tuple for pool
    : return: A tensor that represents convolution and max pooling of x_tensor
    """

    # Convolution
    input_depth = int(x_tensor.shape[-1])
    weight_size = (conv_ksize[0], conv_ksize[1], input_depth, conv_num_outputs)
    conv_strides = (1, conv_strides[0], conv_strides[1], 1)
    weights = tf.Variable(tf.truncated_normal(weight_size, dtype=tf.float32, stddev=0.1))
    bias = tf.Variable(tf.zeros((conv_num_outputs,), dtype=tf.float32))
    conv2d_tensor = tf.nn.conv2d(x_tensor, weights, conv_strides, 'SAME') + bias
    relu_tensor = tf.nn.relu(conv2d_tensor)

    # Maxpooling
    pool_ksize = (1, pool_ksize[0], pool_ksize[1], 1)
    pool_strides = (1, pool_strides[0], pool_strides[1], 1)
    max_tensor = tf.nn.max_pool(relu_tensor, pool_ksize, pool_strides, 'SAME')

    return max_tensor

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_con_pool(conv2d_maxpool)


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Flatten Layer
Implement the flatten function to change the dimension of x_tensor from a 4-D tensor to a 2-D tensor.  The output should be the shape (Batch Size, Flattened Image Size). Shortcut option: you can use classes from the TensorFlow Layers or TensorFlow Layers (contrib) packages for this layer. For more of a challenge, only use other TensorFlow packages.
Can you write Python code for it?

def flatten(x_tensor):
    """
    Flatten x_tensor to (Batch Size, Flattened Image Size)
    : x_tensor: A tensor of size (Batch Size, ...), where ... are the image dimensions.
    : return: A tensor of size (Batch Size, Flattened Image Size).
    """

    # Skipping the batch dimension
    static_dimensions = x_tensor.shape[1:]

    flatten_image_size = 1
    for dimension in static_dimensions:
        flatten_image_size *= int(dimension)

    # Only using basic TensorFlow
    return tf.reshape(x_tensor, [-1, flatten_image_size])

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_flatten(flatten)


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Fully-Connected Layer
Implement the fully_conn function to apply a fully connected layer to x_tensor with the shape (Batch Size, num_outputs). Shortcut option: you can use classes from the TensorFlow Layers or TensorFlow Layers (contrib) packages for this layer. For more of a challenge, only use other TensorFlow packages.
Can you write Python code for it?

def fully_conn(x_tensor, n_outputs):
    """
    Apply a fully connected layer to x_tensor using weight and bias
    : x_tensor: A 2-D tensor where the first dimension is batch size.
    : num_outputs: The number of output that the new tensor should be.
    : return: A 2-D tensor where the second dimension is num_outputs.
    """

    n_inputs = int(x_tensor.shape[1])
    weight_shape = (n_inputs, n_outputs)
    weights = tf.Variable(tf.truncated_normal(weight_shape, stddev=0.1, dtype=tf.float32))
    bias = tf.Variable(tf.zeros(n_outputs), dtype=tf.float32)
    logits = tf.add(tf.matmul(x_tensor, weights), bias)
    activation = tf.nn.relu(logits)

    return activation

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_fully_conn(fully_conn)


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Hyperparameters
Tune the following parameters:
* Set epochs to the number of iterations until the network stops learning or start overfitting
* Set batch_size to the highest number that your machine has memory for.  Most people set them to common sizes of memory:
 * 64
 * 128
 * 256
 * ...
* Set keep_probability to the probability of keeping a node using dropout
Can you write Python code for it?

epochs = 50
batch_size = 256
keep_probability = 1.0


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Implement Preprocess Functions
Normalize
In the cell below, implement the normalize function to take in image data, x, and return it as a normalized Numpy array. The values should be in the range of 0 to 1, inclusive.  The return object should be the same shape as x.
Can you write Python code for it?

def normalize(x):
    """
    Normalize a list of sample image data in the range of 0 to 1
    : x: List of image data.  The image shape is (32, 32, 3)
    : return: Numpy array of normalize data
    """

    x = np.array(x)
    return x/np.max(x)

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_normalize(normalize)


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Output Layer
Implement the output function to apply a fully connected layer to x_tensor with the shape (Batch Size, num_outputs). Shortcut option: you can use classes from the TensorFlow Layers or TensorFlow Layers (contrib) packages for this layer. For more of a challenge, only use other TensorFlow packages.
Note: Activation, softmax, or cross entropy should not be applied to this.
Can you write Python code for it?

def output(x_tensor, n_outputs):
    """
    Apply a output layer to x_tensor using weight and bias
    : x_tensor: A 2-D tensor where the first dimension is batch size.
    : num_outputs: The number of output that the new tensor should be.
    : return: A 2-D tensor where the second dimension is num_outputs.
    """
    n_inputs = int(x_tensor.shape[1])
    weight_shape = (n_inputs, n_outputs)
    weights = tf.Variable(tf.truncated_normal(weight_shape, stddev=0.1, dtype=tf.float32))
    bias = tf.Variable(tf.zeros(n_outputs), dtype=tf.float32)
    output = tf.add(tf.matmul(x_tensor, weights), bias)

    return output

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_output(output)


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Randomize Data
As you saw from exploring the data above, the order of the samples are randomized.  It doesn't hurt to randomize it again, but you don't need to for this dataset.
Preprocess all the data and save it
Running the code cell below will preprocess all the CIFAR-10 data and save it to file. The code below also uses 10% of the training data for validation.
Can you write Python code for it?

"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
# Preprocess Training, Validation, and Testing Data
helper.preprocess_and_save_data(cifar10_dataset_folder_path, normalize, one_hot_encode)


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Train on a Single CIFAR-10 Batch
Instead of training the neural network on all the CIFAR-10 batches of data, let's use a single batch. This should save time while you iterate on the model to get a better accuracy.  Once the final validation accuracy is 50% or greater, run the model on all the data in the next section.
Can you write Python code for it?

"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
print('Checking the Training on a Single Batch...')
with tf.Session() as sess:
    # Initializing the variables
    sess.run(tf.global_variables_initializer())

    # Training cycle
    for epoch in range(epochs):
        batch_i = 1
        for batch_features, batch_labels in helper.load_preprocess_training_batch(batch_i, batch_size):
            train_neural_network(sess, optimizer, keep_probability, batch_features, batch_labels)
        print('Epoch {:>2}, CIFAR-10 Batch {}:  '.format(epoch + 1, batch_i), end='')
        print_stats(sess, batch_features, batch_labels, cost, accuracy)


I am working on the file "2_image-classification/dlnd_image_classification.ipynb".
The first task is:
Train the Neural Network
Single Optimization
Implement the function train_neural_network to do a single optimization.  The optimization should use optimizer to optimize in session with a feed_dict of the following:
* x for image input
* y for labels
* keep_prob for keep probability for dropout
This function will be called for each batch, so tf.global_variables_initializer() has already been called.
Note: Nothing needs to be returned. This function is only optimizing the neural network.
Can you write Python code for it?

def train_neural_network(session, optimizer, keep_probability, feature_batch, label_batch):
    """
    Optimize the session on a batch of images and labels
    : session: Current TensorFlow session
    : optimizer: TensorFlow optimizer function
    : keep_probability: keep probability
    : feature_batch: Batch of Numpy image data
    : label_batch: Batch of Numpy label data
    """

    session.run(optimizer, feed_dict={keep_prob:keep_probability, x:feature_batch, y:label_batch})

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_train_nn(train_neural_network)


I am working on the file "2_kmeans-with-text-data_blank.ipynb".
The first task is:
A few things to notice from the box plot:
* Random initialization results in a worse clustering than k-means++ on average.
* The best result of k-means++ is better than the best result of random initialization.
In general, you should run k-means at least a few times with different initializations and then return the run resulting in the lowest heterogeneity. Let us write a function that runs k-means multiple times and picks the best run that minimizes heterogeneity. The function accepts an optional list of seed values to be used for the multiple runs; if no such list is provided, the current UTC time is used as seed values.
Can you write Python code for it?

def kmeans_multiple_runs(data, k, maxiter, num_runs, seed_list=None, verbose=False):
    heterogeneity = {}

    min_heterogeneity_achieved = float('inf')
    best_seed = None
    final_centroids = None
    final_cluster_assignment = None

    for i in xrange(num_runs):

        # Use UTC time if no seeds are provided
        if seed_list is not None:
            seed = seed_list[i]
            np.random.seed(seed)
        else:
            seed = int(time.time())
            np.random.seed(seed)

        # Use k-means++ initialization
        # YOUR CODE HERE
        initial_centroids = smart_initialize(data, k, seed)

        # Run k-means
        # YOUR CODE HERE
        centroids, cluster_assignment = kmeans(data, k, initial_centroids, maxiter, None, verbose)

        # To save time, compute heterogeneity only once in the end
        # YOUR CODE HERE
        heterogeneity[seed] = compute_heterogeneity(data, k, centroids, cluster_assignment)

        if verbose:
            print('seed={0:06d}, heterogeneity={1:.5f}'.format(seed, heterogeneity[seed]))
            sys.stdout.flush()

        # if current measurement of heterogeneity is lower than previously seen,
        # update the minimum record of heterogeneity.
        if heterogeneity[seed] < min_heterogeneity_achieved:
            min_heterogeneity_achieved = heterogeneity[seed]
            best_seed = seed
            final_centroids = centroids
            final_cluster_assignment = cluster_assignment

    # Return the centroids and cluster assignments that minimize heterogeneity.
    return final_centroids, final_cluster_assignment


I am working on the file "2_kmeans-with-text-data_blank.ipynb".
The first task is:
After initialization, the k-means algorithm iterates between the following two steps:
1. Assign each data point to the closest centroid.
$$
z_i \gets \mathrm{argmin}j \|\mu_j - \mathbf{x}_i\|^2
$$
2. Revise centroids as the mean of the assigned data points.
$$
\mu_j \gets \frac{1}{n_j}\sum{i:z_i=j} \mathbf{x}_i
$$
In pseudocode, we iteratively do the following:
cluster_assignment = assign_clusters(data, centroids)
centroids = revise_centroids(data, k, cluster_assignment)
Assigning clusters
How do we implement Step 1 of the main k-means loop above? First import pairwise_distances function from scikit-learn, which calculates Euclidean distances between rows of given arrays. See this documentation for more information.
For the sake of demonstration, let's look at documents 100 through 102 as query documents and compute the distances between each of these documents and every other document in the corpus. In the k-means algorithm, we will have to compute pairwise distances between the set of centroids and the set of documents.
Can you write Python code for it?

from sklearn.metrics import pairwise_distances

# Get the TF-IDF vectors for documents 100 through 102.
queries = tf_idf[100:102,:]

# Compute pairwise distances from every data point to each query vector.
dist = pairwise_distances(tf_idf, queries, metric='euclidean')

print dist


I am working on the file "2_kmeans-with-text-data_blank.ipynb".
The first task is:
Again, this makes sense since these values are each closer to [0.5 0.5 0] than to [0 -0.5 0].
Given all the data points in a cluster, it only remains to compute the mean. Use np.mean(). By default, the function averages all elements in a 2D array. To compute row-wise or column-wise means, add the axis argument. See the linked documentation for details.
Use this function to average the data points in cluster 0:
Can you write Python code for it?


I am working on the file "2_kmeans-with-text-data_blank.ipynb".
The first task is:
Assessing convergence
How can we tell if the k-means algorithm is converging? We can look at the cluster assignments and see if they stabilize over time. In fact, we'll be running the algorithm until the cluster assignments stop changing at all. To be extra safe, and to assess the clustering performance, we'll be looking at an additional criteria: the sum of all squared distances between data points and centroids. This is defined as
$$
J(\mathcal{Z},\mu) = \sum_{j=1}^k \sum_{i:z_i = j} \|\mathbf{x}_i - \mu_j\|^2.
$$
The smaller the distances, the more homogeneous the clusters are. In other words, we'd like to have "tight" clusters.
Can you write Python code for it?

def compute_heterogeneity(data, k, centroids, cluster_assignment):

    heterogeneity = 0.0
    for i in xrange(k):

        # Select all data points that belong to cluster i. Fill in the blank (RHS only)
        member_data_points = data[cluster_assignment==i, :]

        if member_data_points.shape[0] > 0: # check if i-th cluster is non-empty
            # Compute distances from centroid to data points (RHS only)
            distances = pairwise_distances(member_data_points, [centroids[i]], metric='euclidean')
            squared_distances = distances**2
            heterogeneity += np.sum(squared_distances)

    return heterogeneity


I am working on the file "2_kmeans-with-text-data_blank.ipynb".
The first task is:
Both clusters have mixed content, although cluster 1 is much purer than cluster 0:
* Cluster 0: artists, songwriters, professors, politicians, writers, etc.
* Cluster 1: baseball players, hockey players, football (soccer) players, etc.
Top words of cluster 1 are all related to sports, whereas top words of cluster 0 show no clear pattern.
Roughly speaking, the entire dataset was divided into atheletes and non-atheletes. It would be better if we sub-divided non-atheletes into more categories. So let us use more clusters. How about K=10?
Can you write Python code for it?

k = 10
visualize_document_clusters(wiki, tf_idf, centroids[k](), cluster_assignment[k](), k, map_index_to_word)


I am working on the file "2_kmeans-with-text-data_blank.ipynb".
The first task is:
Checkpoint. For the last time, let us check if Step 1 was implemented correctly. With rows 0, 2, 4, and 6 of tf_idf as an initial set of centroids, we assign cluster labels to rows 0, 10, 20, ..., and 90 of tf_idf. The resulting cluster labels should be [0, 1, 1, 0, 0, 2, 0, 2, 2, 1].
Can you write Python code for it?

if np.allclose(assign_clusters(tf_idf[0:100:10], tf_idf[0:8:2]), np.array([0, 1, 1, 0, 0, 2, 0, 2, 2, 1])):
    print('Pass')
else:
    print('Check your code again.')


I am working on the file "2_kmeans-with-text-data_blank.ipynb".
The first task is:
Checkpoint. Let's check our Step 2 implementation. Letting rows 0, 10, ..., 90 of tf_idf as the data points and the cluster labels [0, 1, 1, 0, 0, 2, 0, 2, 2, 1], we compute the next set of centroids. Each centroid is given by the average of all member data points in corresponding cluster.
Can you write Python code for it?

result = revise_centroids(tf_idf[0:100:10], 3, np.array([0, 1, 1, 0, 0, 2, 0, 2, 2, 1]))
if np.allclose(result[0], np.mean(tf_idf[[0,30,40,60]].toarray(), axis=0)) and \
   np.allclose(result[1], np.mean(tf_idf[[10,20,90]].toarray(), axis=0))   and \
   np.allclose(result[2], np.mean(tf_idf[[50,70,80]].toarray(), axis=0)):
    print('Pass')
else:
    print('Check your code')