I'm following Pytorch seq2seq tutorial and below is how they define the encoder function.
class EncoderRNN(nn.Module):
def __init__(self, input_size, hidden_size):
super(EncoderRNN, self).__init__()
self.hidden_size = hidden_size
self.embedding = nn.Embedding(input_size, hidden_size)
self.gru = nn.GRU(hidden_size, hidden_size)
def forward(self, input, hidden):
embedded = self.embedding(input).view(1, 1, -1)
output = embedded
output, hidden = self.gru(output, hidden)
return output, hidden
def initHidden(self):
return torch.zeros(1, 1, self.hidden_size, device=device)
However, it seems like forward method is never really being called during the training.
Here is how the encoder forward method is being used in the tutorial:
for ei in range(input_length):
encoder_output, encoder_hidden = encoder(input_tensor[ei], encoder_hidden)
encoder_outputs[ei] = encoder_output[0, 0]
isn't it supposed to be encoder.forward instead of just encoder?
Is there some automatic 'forward' mechanism in Pytorch that I am not aware of?
In PyTorch, you write your own class by extending torch.nn.Module and define the forward method to express your desired computational steps that serve as the "paperwork" (e.g. calling hooks) in the model.__call__(...) method (which is what model(x) will call by python special name specifications).
If you are curious you can look at what model(x) does behind the scenes beyond calling model.forward(x) here: https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/module.py#L462
Also, you can see what is the difference between explicitly calling the .foward(x) method and just simply using model(x) here: https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/module.py#L72
Related
I wish to use Allen NLP Interpret for integrated visualization and Saliency mapping.on custom transformer model, can you please tell me how to do that?
It can be done by having AllenNLP wrappers around your custom model. The interpret modules require a Predictor object, so you can write your own, or use an existing one.
Here's an example for a classification model:
from allennlp.data.vocabulary import Vocabulary
from allennlp.predictors.text_classifier import TextClassifierPredictor
from allennlp.data.dataset_readers import TextClassificationJsonReader
import torch
class ModelWrapper(Model):
def __init__(self, vocab, your_model):
super().__init__(vocab)
self.your_model = your_model
self.logits_to_probs = torch.nn.Softmax()
self.loss = torch.nn.CrossEntropyLoss()
def forward(self, tokens, label=None):
if label is not None:
outputs = self.your_model(tokens, label=label)
else:
outputs = self.your_model(tokens)
probs = self.logits_to_probs(outputs["logits"])
if label is not None:
loss = self.loss(outputs["logits"], label)
outputs["loss"] = loss
outputs["probs"] = probs
return outputs
Your custom transformer model may not have an identifiable TextFieldEmbedder. This is the initial embedding layer of your model, against which gradients are calculated for the saliency interpreters. These can be specified by overriding the following methods in the Predictor.
class PredictorWrapper(TextClassifierPredictor):
def get_interpretable_layer(self):
return self._model.model.bert.embeddings.word_embeddings # This is the initial layer for huggingface's `bert-base-uncased`; change according to your custom model.
def get_interpretable_text_field_embedder(self):
return self._model.model.bert.embeddings.word_embeddings
predictor = PredictorWrapper(model=ModelWrapper(vocab, your_model),
dataset_reader=TextClassificationJsonReader())
Now you have an AllenNLP predictor, which can be used with the interpret module as follows:
from allennlp.interpret.saliency_interpreters import SimpleGradient
interpreter = SimpleGradient(predictor)
interpreter.saliency_interpret_from_json({"sentence": "This is a good movie."})
This should give you the gradients with respect to each input token.
In the docs it is written, that "Any C data that you explicitly allocated (e.g. via malloc) in your __cinit__() method should be freed in your __dealloc__() method."
This is not my case. I have following extension class:
cdef class SomeClass:
cdef dict data
cdef void * u_data
def __init__(self, data_len):
self.data = {'columns': []}
if data_len > 0:
self.data.update({'data': deque(maxlen=data_len)})
else:
self.data.update({'data': []})
self.u_data = <void *>self.data
#property
def data(self):
return self.data
#data.setter
def data(self, new_val: dict):
self.data = new_val
Some c function has an access to this class and it appends some data to SomeClass().data dict. What should I write in __dealloc__, when I want to delete the instance of the SomeClass()?
Maybe something like:
def __dealloc__(self):
self.data = None
free(self.u_data)
Or there is no need to dealloc anything at all?
No you don't need to and no you shouldn't. From the documentation
You need to be careful what you do in a __dealloc__() method. By the time your __dealloc__() method is called, the object may already have been partially destroyed and may not be in a valid state as far as Python is concerned, so you should avoid invoking any Python operations which might touch the object. In particular, don’t call any other methods of the object or do anything which might cause the object to be resurrected. It’s best if you stick to just deallocating C data.
You don’t need to worry about deallocating Python attributes of your object, because that will be done for you by Cython after your __dealloc__() method returns.
You can confirm this by inspecting the C code (you need to look at the full code, not just the annotated HTML). There's an autogenerated function __pyx_tp_dealloc_9someclass_SomeClass (name may vary slightly depending on what you called your module) does a range of things including:
__pyx_pw_9someclass_9SomeClass_3__dealloc__(o);
/* some other code */
Py_CLEAR(p->data);
where the function __pyx_pw_9someclass_9SomeClass_3__dealloc__ is (a wrapper for) your user-defined __dealloc__. Py_CLEAR will ensure that data is appropriately reference-counted then set to NULL.
It's a little hard to follow because it all goes through several layers of wrappers, but you can confirm that it does what the documentation says.
I'm developing a simple window that performs some operations at closure. This is my code extract:
from javax.swing import *
from java.awt import *
from java.awt.event import *
from java.io import *
import javax.swing.table.DefaultTableModel as DefaultTableModel
class registro(JFrame):
def __init__(self):
super(registro, self).__init__()
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setExtendedState(JFrame.MAXIMIZED_BOTH)
#[...]
headers = ('Data e orario',
'Personale UO Q&A',
'Tipologia di attività'.decode('utf-8'),
'Personale incontrato con strutture di appartenenza',
'Note')
self.model = DefaultTableModel([["","","","",""]], headers)
self.table = JTable(self.model)
#[...]
self.addWindowListener(self.onClose())
#[...]
def onClose(self):
class saver(WindowAdapter):
tableModel = self.model
def windowClosing(self, event):
print tableModel #HERE IS THE ERROR!!!!!!!!!
return saver()
The error reported on the highlighted line is the following:
NameError: global name 'tableModel' is not defined
Although I have declared the variable inside the listener (to avoid misunderstanding between the two self), I don't understand why it has never been recognized. I'm almost a novice with object-oriented programming and Swing windows on Jython, and I hope this is not my (very) serious shortcoming!
Many thanks in advance.
There's a fairly subtle scope issue here, which is mostly about Python syntax, but also about what code you want to have access to the tableModel. The tableModel variable is not visible by default because you are inside the onClose() function. A defensive solution to this is to explicitly pass the needed variable into the new saver object. I personally prefer this as it more explicitly declares the inputs for saver objects.
class WindowAdapter:
None
class App:
def __init__(self):
self.model = 'DUMMYMODEL'
def onClose(self):
class Saver(WindowAdapter):
def __init__(self,tableModel):
WindowAdapter.__init__(self)
self.tableModel = tableModel
def windowClosing(self,event):
print (self.tableModel)
return Saver(self.model)
if __name__ == '__main__':
app = App()
sv = app.onClose()
sv.windowClosing(event=None)
(This code is cut down and in pure Python to show it is largely scoping related.)
An alternative would be using the Python global keyword to expose the tableModel variable to all lower scopes.
class WindowAdapter:
None
class App:
def __init__(self):
self.model = 'DUMMYMODEL'
def onClose(self):
global tableModel
tableModel = self.model
class Saver(WindowAdapter):
def windowClosing(self,event):
print (tableModel)
return Saver()
if __name__ == '__main__':
app = App()
sv = app.onClose()
sv.windowClosing(event=None)
I'd like to know how to store data from my app so I can review the data when I re-run the app.
e.g. I type some info in a TextInput and then when I click the submit button, the info is pasted in a label, so I close the app and when I reopen it the info should be appearing in the label. I know that there are sqlite3 and mysql but I don't know how to apply it into my python/kivy code.
Please anyone suggest me how that can be done.
If possible show with an example, it would be perfect.
Thanks in advance,
My py code:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from random import shuffle
from kivy.core.window import Window
Window.clearcolor = [1, 1, 1, 1]
Window.size = (550, 650)
Builder.load_file('builder.kv')
class MainScreen(ScreenManager):
pass
class Menu(Screen):
pass
class Levels(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def on_pre_enter(self):
Window.bind(on_keyboard=self.voltar)
def voltar(self, window, key, *args):
if key == 27:
App.get_running_app().root.current = 'menu'
return True
def on_pre_leave(self):
Window.unbind(on_keyboard=self.voltar)
class LvLogos(Screen):
def on_pre_enter(self):
Window.bind(on_keyboard=self.voltar)
def voltar(self, window, key, *args):
if key == 27:
App.get_running_app().root.current = 'menu'
return True
def on_pre_leave(self):
Window.unbind(on_keyboard=self.voltar)
class Logo(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def shuffle(self):
letter = self.letters
self.s = shuffle(letter)
return letter
def on_pre_enter(self):
Window.bind(on_keyboard=self.voltar)
def voltar(self, window, key, *args):
if key == 27:
App.get_running_app().root.current = 'menu'
return True
def on_pre_leave(self):
Window.unbind(on_keyboard=self.voltar)
class LvShields(Screen):
pass
class Shield(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def shuffle(self):
letter = self.letters
self.s = shuffle(letter)
return letter
class QuizZApp(App):
def build(self):
self.icon = 'C:\\Users\\gusta\\PycharmProjects\\QuizzApp\\Images\\QuizzLogo.png'
return MainScreen()
if __name__ == '__main__':
QuizZApp().run()
Of course you can use sqlite3, but the simplest way to store basic data for kivy app like your exaple would be to use json file with kivy's own JsonStore class.
It has the benefit of allocating your file in the right place depending on the platform it is deployed on, you won't need to care where exactly.
Here is a simple example using get(), put() and exists() methods to store typed text from TextInput and load it on a Label. (You won't need to create the file itself, just initialize the object and write (put()) in it).
from kivy.uix.boxlayout import BoxLayout
from kivy.storage.jsonstore import JsonStore
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.properties import ObjectProperty
kv='''
RootWidget:
orientation: 'vertical'
BoxLayout:
TextInput:
id: txtinpt
Label:
id: lbl
text: root.stored_data.get('mydata')['text'] if root.stored_data.exists('mydata') else ''
Button:
size_hint_y: .3
text: 'Submit'
on_press:
root.stored_data.put('mydata', text=txtinpt.text)
lbl.text = txtinpt.text
'''
class RootWidget(BoxLayout):
stored_data = ObjectProperty(None)
def __init__(self, *args, **kwargs):
super(BoxLayout, self).__init__(*args, **kwargs)
self.stored_data = JsonStore('data.json')
runTouchApp(Builder.load_string(kv))
If you are new to Json, it is a file containing list of pairs, which's value by its own may be a new list of pair. pretty much like python's dict.
For kivy's JsonStore class, it assume you are working with a minimum of two levels, hence {"mydata": {"text": "What you have written last run"}}. It doesn't make much sense in this simple example to have a nested dict, but in general it will be exactly what you want for real applications, like if you wanted to take contacts data for multiple contacts, or you want to store various configurations for multiple widget for the app itself (in this case you may want to read (get()) the data prior of loading the widgets, probably in the App-class's build() method).
reference: https://kivy.org/docs/api-kivy.storage.html
I'm learning Backbone.js and Flask (and Flask-sqlalchemy). I chose Flask because I read that it plays well with Backbone implementing RESTful interfaces. I'm currently following a course that uses (more or less) this model:
class Tasks(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80), unique=True)
completed = db.Column(db.Boolean, unique=False, default=False)
def __init__(self, title, completed):
self.title = title
self.completed = completed
def json_dump(self):
return dict(title=self.title, completed=self.completed)
def __repr__(self):
return '<Task %r>' % self.title
I had to add a json_dump method in order to send JSON to the browser. Otherwise, I would get errors like object is not JSON serializable, so my first question is:
Is there a better way to do serialization in Flask? It seems that some objects are serializable but others aren't, but in general, it's not as easy as I expected.
After a while, I ended up with the following views to take care of each type of request:
#app.route('/tasks')
def tasks():
tasks = Tasks.query.all()
serialized = json.dumps([c.json_dump() for c in tasks])
return serialized
#app.route('/tasks/<id>', methods=['GET'])
def get_task(id):
tasks = Tasks.query.get(int(id))
serialized = json.dumps(tasks.json_dump())
return serialized
#app.route('/tasks/<id>', methods=['PUT'])
def put_task(id):
task = Tasks.query.get(int(id))
task.title = request.json['title']
task.completed = request.json['completed']
db.session.add(task)
db.session.commit()
serialized = json.dumps(task.json_dump())
return serialized
#app.route('/tasks/<id>', methods=['DELETE'])
def delete_task(id):
task = Tasks.query.get(int(id))
db.session.delete(task)
db.session.commit()
serialized = json.dumps(task.json_dump())
return serialized
#app.route('/tasks', methods=['POST'])
def post_task():
task = Tasks(request.json['title'], request.json['completed'])
db.session.add(task)
db.session.commit()
serialized = json.dumps(task.json_dump())
return serialized
In my opinion, it seems a bit verbose. Again, what is the proper way to implement them? I have seen some extensions that offer RESTful interfaces in Flask but those look quite complex to me.
Thanks
I would use a module to do this, honestly. We've used Flask-Restless for some APIs, you might take a look at that:
https://flask-restless.readthedocs.org/en/latest/
However, if you want build your own, you can use SQLAlchemy's introspection to output your objects as key/value pairs.
http://docs.sqlalchemy.org/en/rel_0_7/core/schema.html#metadata-reflection
Something like this, although I always have to triple-check I got the syntax right, so take this as a guide more than working code.
#app.route('/tasks')
def tasks():
tasks = Tasks.query.all()
output = []
for task in tasks:
row = {}
for field in Tasks.__table__.c:
row[str(field)] = getattr(task, field, None)
output.append(row)
return jsonify(data=output)
I found this question which might help you more. I'm familiar with SQLAlchemy 0.7 and it looks like 0.8 added some nicer introspection techniques:
SQLAlchemy introspection
Flask provides jsonify function to do this. Check out its working here.
Your json_dump method is right though code can be made concise. See this code snippet
#app.route('/tasks')
def tasks():
tasks = Tasks.query.all()
return jsonify(data=[c.json_dump() for c in tasks])