module 'pymc3' has no attribute 'traceplot' Error - pymc3

I'm trying to generate a trace plot of my model but it shows module 'pymc3' has no attribute 'traceplot' error. My code is:
with pm.Model() as our_first_model:
# a priori
theta = pm.Beta('theta', alpha=1, beta=1)
# likelihood
y = pm.Bernoulli('y', p=theta, observed=data)
#y = pm.Binomial('theta',n=n_experimentos, p=theta, observed=sum(datos))
start = pm.find_MAP()
step = pm.Metropolis()
trace = pm.sample(1000, step=step, start=start)
burnin = 0 # no burnin
chain = trace[burnin:]
pm.traceplot(chain, lines={'theta':theta_real});
which then gives the following error:
AttributeError Traceback (most recent call last)
<ipython-input-8-40f97a342e0f> in <module>
1 burnin = 0 # no burnin
2 chain = trace[burnin:]
----> 3 pm.traceplot(chain, lines={'theta':theta_real});
AttributeError: module 'pymc3' has no attribute 'traceplot'
I'm on windows10 and I've downloaded pymc3 with pip since it was not included in anaconda that I've downloaded.

Since several versions ago, PyMC3 delegates plotting and stats to ArviZ, and the original plotting commands were kept as alias to ArviZ methods for convenience and ease of transition.
Latest PyMC3 release (3.11.0) is the first to not include the alias such as pm.traceplot. You have to use arviz.plot_trace which works with PyMC3 objects.
Extra notes unrelated to the question itself:
You are using pm.find_MAP to initialize the chain and you are manually setting the sampler to pm.Metropolis instead of allowing pm.sample to select its own defaults. There are reasons to do so and it's not intrinsically wrong but it is discourged, see PyMC3 FAQs.
PyMC3 is transitioning to using InferenceData as default output of pm.sample. I would recommend setting return_inferencedata=True in pm.sample for the following reasons: 1) ArviZ functions convert to this format under the hood, you will avoid this small overhead, 2) InferenceData has more capabilities than MultiTrace, 3) PyMC3 is transitioning to InferenceData as the default output of pm.sample so why not get started already?
You have a # no burn-in comment, however, the trace returned by pm.sample has already had a burn-in performed of length the tune parameter passed to it. The default value of tune is 1000. To actually get all the samples and see how the MCMC slowly converges to the typical set, you need to use discard_tuned_samples=False.
Some InferenceData resources:
InferenceData overview: https://arviz-devs.github.io/arviz/getting_started/XarrayforArviZ.html
Working with InferenceData examples (shows how to perform burn-in among other things): https://arviz-devs.github.io/arviz/getting_started/WorkingWithInferenceData.html

Related

How to use Keras SavedModel from C++

I have a trained a classic CNN(pre-trained mobile net) for image classification. I want to now use this model from c++. From my understanding, I need to create a library of the model, that can accept the input and return its outputs. I have the model saved in format .pb (SavedModel).
I have already tried, CppFlow, where the error shows that it can't read my model. I assume it's due to incompatibility with TF 2.0.
I have also got the command line interface of SavedModel working, but I don't know how to use it in my cpp application.
I want to know how I can build a library of my model and use this library such that it can make predictions on the fly. Any guidance will be helpful. Please let me know if any additional information is required.
One way of using keras model in C++ is to convert it to TensorFlow .pb format. I've just composed a script for doing this, down below.
Usage: python script.py keras_model.hdf5
It outputs tensorflow model as input file name appended by .pb.
Then you can use TF C++ api for reading model and doing inference. Nice detailed example of using image recognition model to label images in C++ TF is located here.
Another option - you may use Keras directly by calling Python API from C++, it is not that difficult, there is standalone python which is compiled statically meaning having no dll/shared libs dependencies at all hence python interpreter can be fully compiled into C++ single binary. There are also many libraries in Internet that help you to easily run Python from C++.
import sys, os
from keras import backend as K
from keras.models import load_model
import tensorflow as tf
def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):
"""
Freezes the state of a session into a pruned computation graph.
Creates a new computation graph where variable nodes are replaced by
constants taking their current value in the session. The new graph will be
pruned so subgraphs that are not necessary to compute the requested
outputs are removed.
#param session The TensorFlow session to be frozen.
#param keep_var_names A list of variable names that should not be frozen,
or None to freeze all the variables in the graph.
#param output_names Names of the relevant graph outputs.
#param clear_devices Remove the device directives from the graph for better portability.
#return The frozen graph definition.
"""
from tensorflow.python.framework.graph_util import convert_variables_to_constants
graph = session.graph
with graph.as_default():
freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
output_names = output_names or []
output_names += [v.op.name for v in tf.global_variables()]
# Graph -> GraphDef ProtoBuf
input_graph_def = graph.as_graph_def()
if clear_devices:
for node in input_graph_def.node:
node.device = ""
frozen_graph = convert_variables_to_constants(session, input_graph_def,
output_names, freeze_var_names)
return frozen_graph
if len(sys.argv) <= 1:
print('Usage: python script.py keras_model.hdf5')
sys.exit(0)
else:
ifname = sys.argv[1]
model = load_model(ifname)
frozen_graph = freeze_session(
K.get_session(),
output_names = [out.op.name for out in model.outputs],
)
tf.io.write_graph(frozen_graph, os.path.dirname(ifname), ifname + '.pb', as_text = False)
There are standalone third-party libraries that can import keras model into c++ for inference without doing much of work from our side.
Examples are
Multithreaded library for image segmentation models such as U-Net etc. - https://github.com/upashu1/keras2cpp_multithreading_image_segmentation
A library that supports the most of the layers
https://github.com/Dobiasd/frugally-deep

serving_input_receiver_fn() function without the deprecated tf.placeholder method in TF 2.0

I have a functioning tf.estimator pipeline build in TF 1, but now I made the decision to move to TF 2.0, and I have problems in the end of my pipeline, when I want to save the model in the .pb format
I'm using this high level estimator export_saved_model method:
https://www.tensorflow.org/api_docs/python/tf/estimator/BoostedTreesRegressor#export_saved_model
I have two numeric features, 'age' and 'time_spent'
They're defined using tf.feature_column as such:
age = tf.feature_column.numeric_column('age')
time_spent = tf.feature_column.numeric_column('time_spent')
features = [age,time_spent]
After the model has been trained I turn the list of features into a dict using the method feature_column_make_parse_example_spec() and feed it to another method build_parsing_serving_input_receiver_fn() excactly as outlied on tensorflow's webpage, https://www.tensorflow.org/guide/saved_model under estimators.
columns_dict = tf.feature_column_make_parse_example_spec(features)
input_receiver_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(columns_dict)
model.export_saved_model(export_dir,input_receiver_fn)
I then inspect the output using the CLI tools
saved_model_cli show --dir mydir --all:
Resulting in the following:
enter image description here
Somehow Tensorflow squashes my two usefull numeric features into a useless string input crap called "inputs".
In TF 1 this could be circumvented by creating a custom input_receiver_fn() function using some tf.placeholder method, and I'd get the correct output with two distinct numeric features. But tf.placeholder doesn't exist in TF 2, so now it's pretty useless.
Sorry about the raging, but Tensorflow is horribly documented, and I'm really working with high level API's and it should just be straight out on the horse, but no.
I'd really appreciate any help :)
Tensorflow squashes my two usefull numeric features into a useless
string input crap called "inputs"
is not exactly true, as the exported model expects a serialized tf.Example proto. So, you can warp your age and time_spent into two features which will look like:
features {
feature {
key: "age"
value {
float32_list {
value: 10.2
}
}
}
feature {
key: "time_spent"
value {
float32_list {
value: 40.3
}
}
}
}
you can then call your regress function with the serialized string.

AttributeError: 'module' object has no attribute 'setup_graph'

I am new to deep learning and trying to implement code written here
http://r2rt.com/recurrent-neural-networks-in-tensorflow-i.html.
I am trying to implement same code but I am getting error
no module name basic_rnn
while importing basic_rnn as written in the code:
import basic_rnn
def plot_learning_curve(num_steps, state_size=4, epochs=1):
global losses, total_loss, final_state, train_step, x, y, init_state
tf.reset_default_graph()
g = tf.get_default_graph()
losses, total_loss, final_state, train_step, x, y, init_state = \
basic_rnn.setup_graph(g,basic_rnn.RNN_config(num_steps=num_steps, state_size=state_size))
res = train_network(epochs, num_steps, state_size=state_size, verbose=False)
plt.plot(res)
then I changed basic_rnn = tf.contrib.rnn.BasicRNNCell,
then I am getting error
'module' object has no attribute 'setup_graph'.
I am assuming I will again get error in while implementing basic_rnn.RNN_config.
What would be the correct syntax?
I am using tensorflow of version 1.0.0
pls help
You can look at the gist code provided by the author, r2rt:
https://gist.github.com/anonymous/5fc9903990ecec5f09361934920bb999. Though you need to tweak the code a bit to get it run.
Basically, you need to implement the setuo_graph and RNN_config functions in basic_rnn.py. But since there are three versions of RNNs that the original blog is comparing, I think it would be better if you put RNN_config in one Python file.
Besides, I found some of r2rt's code is deprecated, so I adapted the code and created my own repo. Check it out if you are interested:
https://github.com/innerfirexy/rnn-tf-r2rt
You can run the code in run_RNNs.py in IPython. I changed the gist code a bit by moving the RNN_config function to train.py, and giving train_network a config parameter.

Importing scipy stats modules to get expected value of empirical distribution

I want to fit every member of a list of data sets to a lognormal distribution. Then, I want to calculate the expected value of a function over each distribution. I've tried the following code and get the following error.
Code
from numpy import *
from scipy.stats import lognorm
dists = map(lognorm,data)
expectations = [dist.expect(r_[1,1],zeros(40,)) for dist in dists]
Error
AttributeError: 'rv_frozen' object has no attribute 'expect'
Perhaps I'm reading the documentation incorrectly, I though because expect is a method of lognormal it is available to frozen distributions.
What is the right way to call the methods such as 'expect' from a frozen distribution?
see thread at
http://mail.scipy.org/pipermail/scipy-user/2012-August/032860.html
expect is not yet connected to frozen distributions. Either, use a distribution that is not frozen or use a helper function like
def expect(X, f, lb, ub):
if hasattr(X, 'dist'):
return X.dist.expect(f, lb = lb, ub = ub)
else:
return X.expect(f, lb = lb, ub = ub)
update:
Besides the problem with the frozen distribution, you need to check the methods of the distributions.
You need to use .fit(data, ...) to estimate the parameters.
You can calculate an expected value of a function using expect, the signature is here http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.expect.html?highlight=expect#scipy.stats.rv_continuous.expect
Default of expect is the identity mapping that calculates the mean. But you can also get the mean directly form the distribution using either the .mean or the .stats method. This avoids the integration if there is an explicit expression for the mean.
if you look at the Scjipy Frozen Object, you see that expect is no method of it.
Try :
from numpy import *
from scipy.stats import lognorm
dists = map(lognorm,data)
expectations = [ lognorm.expect( func, s, loc ) for dist in dists]
( I do not know the functions options )

QuantLib + Python: TARGET() macro and default calendar (RuntimeError: option expired)

I am using Quantlib to perform calculations on historic data.
After setting up the required framework (curves etc), When I call option.ImpliedVolatility() I get the following exception thrown (for options that have expired):
File "/usr/local/lib/python2.6/dist-packages/QuantLib/QuantLib.py", line 3683, in impliedVolatility
def impliedVolatility(self, *args): return _QuantLib.VanillaOption_impliedVolatility(self, *args)
RuntimeError: option expired
A snippet of the lines of code for setting up required curves etc is shown below:
dividend_yield = YieldTermStructureHandle(FlatForward(0, TARGET(), div_yield, Actual365Fixed()))
risk_free_rate = YieldTermStructureHandle(FlatForward(0, TARGET(), rf_rate, Actual365Fixed()))
volatility = BlackVolTermStructureHandle(BlackConstantVol(0, TARGET(), annualized_histvol, Actual360()))
I STRONGLY suspect that the TARGET() macro used defaults to the current system date.
How may I set up the library to use a specific historic date?
The evaluation date is set by running, say,
Settings.instance().evaluationDate = Date(14,March,2010)
before the calculations. If not set, it defaults to the current date as you suspected.
The TARGET calendar just tells the curve what days are holidays, but has no effect on the evaluation date itself.