patternpythonMinor
Defensive programming type-checking
Viewed 0 times
typeprogrammingcheckingdefensive
Problem
I have issues with dynamically typed languages, and I tend to worry about type a lot.
Numpy has different behaviour depending on if something is a matrix or a plain ndarray, or a list. I didn't originally have all these asserts, but I inserted them while trying to debug a type error.
Is there a better way? Perhaps a defensive programming toolkit? There is also duplication in the code, but I can't see a nice way of removing it while maintaining meaning. People familiar with Restricted Boltzman Machines will recognise the conditional formula used for Gibbs sampling for contrastive divergence.
Numpy has different behaviour depending on if something is a matrix or a plain ndarray, or a list. I didn't originally have all these asserts, but I inserted them while trying to debug a type error.
from numpy import *
sigmoid = vectorize(lambda(x): 1.0/(1.0+exp(-x)))
def prob_hOn_givenV (v,b,w):
assert isinstance(v,matrix)
assert isinstance(w,matrix)
assert isinstance(b,matrix)
assert shape(v)[1]==shape(w)[0]
#print("|v|="+str(shape(v)) +"|w|="+str(shape(w)) )
return sigmoid(b+v*w) #sum up rows (v is a column vector)
def prob_vOn_givenH (h,a,w):
assert isinstance(h,matrix)
assert isinstance(a,matrix)
assert isinstance(w,matrix)
assert shape(h)[1]==shape(w.T)[0]
return sigmoid(a+h*w.T) #sum up columns. (h is a row vector)Is there a better way? Perhaps a defensive programming toolkit? There is also duplication in the code, but I can't see a nice way of removing it while maintaining meaning. People familiar with Restricted Boltzman Machines will recognise the conditional formula used for Gibbs sampling for contrastive divergence.
Solution
First, I recommend avoiding the
Second, the idiomatic way to do this kind of thing in numpy is not to assert that the inputs are particular types, but to coerce them to an
matrix type altogether. The problems it causes outweighs the minor syntactical convenience it provides, in my (and quite a few others') opinion.Second, the idiomatic way to do this kind of thing in numpy is not to assert that the inputs are particular types, but to coerce them to an
ndarray. np.asarray() does this efficiently; if the input is an ndarray, the input passes through untouched; if it is an ndarray subclass, then a new ndarray will be created but only as a view on the original data so no data will be copied.import numpy as np
def sigmoid(x):
# No need to use vectorize() for this. It's already vectorized.
return 1.0 / (1.0 + np.exp(-x))
def prob_hOn_givenV(v, b, w):
v = np.asarray(v)
b = np.asarray(b)
w = np.asarray(w)
# Don't bother checking the shape. `np.dot()` will do that for us.
# Strictly speaking, the `asarray(v)` and `asarray(w)` aren't necessary
# since `np.dot(v, w)` already does that internally. But it does no harm.
return sigmoid(b + np.dot(v, w))Code Snippets
import numpy as np
def sigmoid(x):
# No need to use vectorize() for this. It's already vectorized.
return 1.0 / (1.0 + np.exp(-x))
def prob_hOn_givenV(v, b, w):
v = np.asarray(v)
b = np.asarray(b)
w = np.asarray(w)
# Don't bother checking the shape. `np.dot()` will do that for us.
# Strictly speaking, the `asarray(v)` and `asarray(w)` aren't necessary
# since `np.dot(v, w)` already does that internally. But it does no harm.
return sigmoid(b + np.dot(v, w))Context
StackExchange Code Review Q#39125, answer score: 2
Revisions (0)
No revisions yet.