how to implement tent activation function in pytorch? - torch

I need to create tent activation function as it is shown in the following image.
I was wondering if there is torch built-in tent activation function?
If not, is there any way to create this activation function?
Thanks

I think this can be used.
y = (x>0)*(1-x>0)*(1-x) + (x<0)*(1+x>0)*(1+x)

I found simple solution to implement the tent activation function in forward function
import torch
import torch.nn as nn
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
def forward(self, input):
out = nn.functional.relu(input + 1) - 2 * nn.functional.relu(input) + nn.functional.relu(input - 1)
return out
same solution could be implemented using
nn.ReLU()
as the layers of network.

This should work:
torch.maximum(1 - x.abs(), 0)

Related

PyQt5 - encapsulate / make a component reusable - example: QTimer/QLabel implementation outside of parent class

I implement a label that displays the current time in several of my PyQt5 applications. Here is a MRE:
import sys
import logging
from PyQt5 import QtWidgets, QtCore, QtGui
__log__ = logging.getLogger()
class App(QtWidgets.QApplication):
def __init__(self, sys_argv):
super(App, self).__init__(sys_argv)
self.main_view = MainView()
self.main_view.show()
class MainView(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setObjectName("MreUi")
self.resize(300, 100)
self.setWindowTitle('MreUi')
self.label = QtWidgets.QLabel()
self.setCentralWidget(self.label)
config_clock(self.label)
self.start_clocks()
def start_clocks(self):
timer = QtCore.QTimer(self)
timer.timeout.connect(self.show_time)
timer.start(1000)
def show_time(self):
current_time = QtCore.QTime.currentTime()
clock_label_time = current_time.toString('hh:mm:ss')
self.label.setText(clock_label_time)
def config_clock(label):
label.setAlignment(QtCore.Qt.AlignCenter)
font = QtGui.QFont('Arial', 24, QtGui.QFont.Bold)
label.setFont(font)
if __name__ == '__main__':
logging.basicConfig()
app = App(sys.argv)
try:
sys.exit(app.exec_())
except Exception as e:
__log__.error('%s', e)
As I implemented a similar clock in several of my PyQt apps, I thought it would be nice to implement it as a component / encapsulate it. First I thought of doing this by calling a config_clock function from any QWidget, and have that function do ~ALL of the work implementing the clock for the specified label. This would avoid having to repeat myself in multiple applications from writing/calling start_clocks and show_time instance methods of MainView. but as I started to code that ...
# from inside my QWidget:
config_clock(self.label)
# this function would live outisde the class, thus reusable by diff Qt apps:
def config_clock(label):
# start the clock
# set default font, etc for label
# instantiate QtCore.QTimer
# # but that's when I realized I've always passed self to QtCore.QTimer and that maybe encapsulating this isn't as trivial as I thought.
Should I create some kind of ClockLabel() object of my own that gets passed a QtWidget's label and can also be an instance attribute of each QtWidget that might need it? That smells kind of clunky to me. But surely there must be a way to make a 'reusable component' in PyQt, I just don't know how...
I also am not certain if the MainView(QtWidgets.QMainWindow) could rightly be referred to as the 'parent class' if I were to pass it as a parameter to a ClockLabel() class I write or a config_clock function whose signature could look like:
def config_clock(label, parent_qtwidget):
# also feels clunky and not sure if parent would be the right term
Thanks
With QtWidgets it is normal to specialize widgets by inheritance. Here is an example of how you might rearrange your code to produce a reusable widget:
class ClockLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.setAlignment(QtCore.Qt.AlignCenter)
font = QtGui.QFont('Arial', 24, QtGui.QFont.Bold)
self.setFont(font)
self._timer = QtCore.QTimer(self)
self._timer.timeout.connect(self._show_time)
def start(self):
self._timer.start(1000)
def stop(self):
self._timer.stop()
def _show_time(self):
current_time = QtCore.QTime.currentTime()
clock_label_time = current_time.toString('hh:mm:ss')
self.setText(clock_label_time)

Best approach to show / hide dialogs

I have encountered a theoretical question. I'm using pyqt5, but this is probably are very generalistic and framework independent question.
I have a QMainwindow sitting around waiting for the user to do stuff. The user can show / hide dialogues (subclasses of QDockwidgets) as he chooses using the QMenu and the associated shortcuts (it's a checkable QAction for each individual dialogue).
I have been struggling with showing / hiding the dialogues efficiently. Currently, I'm just initiating them all at start up, hiding those that I don't want to show up in the beginning. This makes triggering the dialogues easy, since I can just dialogue.show() /dialogue.hide() depending on the dialogues current visibility.
But I cannot believe that this is best practice and very efficient.
I have tried (I currently do not have my pyqt environment set up on this computer, so I had to strip down my actual code without being able to test if this runs):
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class InfoPanel(QDockWidget):
def __init__(self, title='Tool Box'):
QDockWidget.__init__(self, title)
self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetClosable)
self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
frame = QFrame()
layout = QGridLayout()
self.canvas = QGraphicsView()
self.canvas.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(40, 40, 40)))
layout.addWidget(self.canvas)
frame.setLayout(layout)
self.setWidget(frame)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.showpanelAct = QAction("&Show Panel", self, enabled=True,checkable=True, shortcut="F10")
self.showpanelAct.triggered.connect(lambda: self.showPanel(0))
self.viewMenu = QMenu("&View", self)
self.viewMenu.addAction(self.showpanelAct)
self.setDockOptions(QMainWindow.AnimatedDocks)
def showPanel(self,i:int = 0): # this is not so smart - should construct and deconstuct to save memory!?
if i == 0: #infopanel
dialogueExists = True
try: self.infoPanel
#except NameError: #does not catch the error
except:
dialogueExists = False
if dialogueExists:
print('destroy')
self.infoPanel.destroy()
else:
print('create')
self.infoPanel = InfoPanel() #init
self.infoPanel.show()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
Which works the first time, but after that, it only seems to trigger the destruction of the dialogue (which, surprisingly, does not crash anything it just keeps on going).
Why is that and is there a standard way to approach the showing hiding of dialogues?
I took the exposed MCVE of OP and tried to make it running in my cygwin64 on Windows 10.
At first I had to apply little fixes. (OP stated that he was not able to test it at the time of publishing.)
First, I inserted a “hut” at first line for convenient start in bash:
#!/usr/bin/python3
Second, the self.viewMenu didn't appear. Hence, I inserted a line after
self.viewMenu = QMenu("&View", self)
self.viewMenu.addAction(self.showpanelAct)
to add the viewMenu to main menu bar:
self.menuBar().addMenu(self.viewMenu)
which fixed it.
Third, when clicking the menu item I got:
Traceback (most recent call last):
File "./testQDockPanelShowHide.py", line 27, in <lambda>
self.showpanelAct.triggered.connect(lambda: self.showPanel(0))
File "./testQDockPanelShowHide.py", line 45, in showPanel
self.infoPanel = InfoPanel() #init
File "./testQDockPanelShowHide.py", line 17, in __init__
self.canvas.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(40, 40, 40)))
NameError: name 'QtGui' is not defined
Aborted (core dumped)
I must admit that my Python knowledge is very limited. (I'm the guy who writes the Python bindings in C++ for the colleagues. So, my colleagues are the actual experts. At most, I play a little bit in Python when I test whether new implemented bindings do what's expected.) However, I modified
self.canvas.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(40, 40, 40)))
to:
self.canvas.setBackgroundBrush(QBrush(QColor(40, 40, 40)))
which fixed this issue.
After this, I got the behavior described by OP and did a closer look where I (and OP) suspected the error:
def showPanel(self,i:int = 0): # this is not so smart - should construct and deconstuct to save memory!?
if i == 0: #infopanel
dialogueExists = True
try: self.infoPanel
#except NameError: #does not catch the error
except:
dialogueExists = False
if dialogueExists:
print('destroy')
self.infoPanel.destroy()
else:
print('create')
self.infoPanel = InfoPanel() #init
self.infoPanel.show()
I strongly believe that try: self.infoPanel doesn't do what OP thinks it would.
It tries to access self.infoPanel which isn't existing until the first call of this method. (Please, be aware, the member variable self.infoPanel isn't existing.) So, the except: branch is executed and sets dialogueExists = False which a few lines later causes self.infoPanel = InfoPanel() #init. Now, the member variable self.infoPanel is existing, and the try: self.infoPanel will never fail again until destruction of this MainWindow.
Out of curiosity, I had a look at QWidget.destroy() (to be sure not to tell something wrong):
QWidget.destroy (self, bool destroyWindow = True, bool destroySubWindows = True)
Frees up window system resources. Destroys the widget window if destroyWindow is true.
destroy() calls itself recursively for all the child widgets, passing destroySubWindows for the destroyWindow parameter. To have more control over destruction of subwidgets, destroy subwidgets selectively first.
This function is usually called from the QWidget destructor.
It definitely doesn't destroy the member variable self.infoPanel.
After having understood this, a fix was easy and obvious:
def showPanel(self,i:int = 0): # this is not so smart - should construct and deconstuct to save memory!?
if i == 0: #infopanel
try: self.infoPanel
#except NameError: #does not catch the error
except:
print('create')
self.infoPanel = InfoPanel() #init
if self.infoPanel.isVisible():
self.infoPanel.hide()
else:
self.infoPanel.show()
Btw. I replaced destroy() by hide() which makes a re-creation of the InfoPanel() obsolete.
I tested this by toggling the menu item multiple times – it works as expected now (at least, it looks like).
The complete sample finally:
#!/usr/bin/python3
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class InfoPanel(QDockWidget):
def __init__(self, title='Tool Box'):
QDockWidget.__init__(self, title)
self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetClosable)
self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
frame = QFrame()
layout = QGridLayout()
self.canvas = QGraphicsView()
# self.canvas.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(40, 40, 40)))
self.canvas.setBackgroundBrush(QBrush(QColor(40, 40, 40)))
layout.addWidget(self.canvas)
frame.setLayout(layout)
self.setWidget(frame)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.showpanelAct = QAction("&Show Panel", self, enabled=True,checkable=True, shortcut="F10")
self.showpanelAct.triggered.connect(lambda: self.showPanel(0))
self.viewMenu = QMenu("&View", self)
self.viewMenu.addAction(self.showpanelAct)
self.menuBar().addMenu(self.viewMenu)
self.setDockOptions(QMainWindow.AnimatedDocks)
def showPanel(self,i:int = 0): # this is not so smart - should construct and deconstuct to save memory!?
if i == 0: #infopanel
try: self.infoPanel
#except NameError: #does not catch the error
except:
print('create')
self.infoPanel = InfoPanel() #init
if self.infoPanel.isVisible():
self.infoPanel.hide()
else:
self.infoPanel.show()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
After taking a break from coding the solution to my problem was very obvious. Going back to my original code (which did not produce the expected output of creating / destroying the dialogue self.infoPanel on demand):
dialogueExists = True
try: self.infoPanel
#except NameError: #does not catch the error
except:
dialogueExists = False
if dialogueExists:
print('destroy')
self.infoPanel.destroy()
else:
print('create')
self.infoPanel = InfoPanel() #init
self.infoPanel.show()
My main problem was that I confused two separate things. Qt destroyed the widget contained in the object self.infoPanel when I called self.infoPanel.destroy(). But that doesn't mean the object self.infoPanel does not exist (that's exactly what I use try: ... for, to see if the object exists). The simple and obvious way to create and destroy dialogues on demand obviously involves deleting the object from the environment (del self.infoPanel).
The working code is:
dialogueExists = True
try:
self.infoPanel.destroy() #not sure this is needed, but I guess it doesn't hurt
del self.infoPanel #this is the deletion of the actual object
except:
dialogueExists = False
if not dialogueExists :
self.infoPanel = InfoPanel()
Cheers and many thanks for the helpful advice on deciding whether to show / hide dialogues or to create / destroy them!

OpenMDAO: How to handle non-converging points in ExplicitComponent.compute?

I've tried to handle non-converging points in the compute method of my ExplicitComponent, by raising an AnalysisError, as suggested in What is the best way to tell openMDAO driver or solver that it is impossible to evaluate the model at some point? (originally I wanted to make a comment in this thread, but I wasn't allowed due to my low Stack Overflow reputation score). However, this doesn't seem to solve my problem. What I expected was that error would be caught, the design point would be skipped and that the optimizer would continue to evaluate other points in order to find a solution. It is correct that the error is caught, but for some reason, the error is then reraised in ScipyOptimizeDriver.run. What is the purpose of this?
This is an example script for reproducing the behaviour:
import numpy as np
from openmdao.api import Problem, Group, IndepVarComp, ExplicitComponent, ScipyOptimizeDriver, ScipyKrylov, AnalysisError
class Test1Comp(ExplicitComponent):
def setup(self):
self.add_input('design_x', 1.0)
self.add_input('design_y', 1.0)
self.add_input('design_z', 0.5)
self.add_output('y', val=0.1)
self.add_output('z', val=0.1)
self.add_output('obj', val=0.0)
self.declare_partials(of='*', wrt='*', method='fd', form='central', step=1.0e-4)
def compute(self, inputs, outputs):
design_z = inputs['design_z']
design_x = inputs['design_x']
design_y = inputs['design_y']
# Let's assume we have a model that has problems converging around design_x = 5.0
if 0.49999 < design_x < 0.500001:
raise AnalysisError()
z = 4/(design_z + 1)
y = - design_z - 2*z
obj = (y/5.833333 - design_x)**2 + z/2.666667*100*(design_y - design_x**2)**2
outputs["z"] = z
outputs["y"] = y
outputs['obj'] = obj
if __name__ == "__main__":
prob = Problem()
model = prob.model = Group()
model.add_subsystem('d1', IndepVarComp('design_x', 1.0))
model.add_subsystem('d2', IndepVarComp('design_y', 1.0))
model.add_subsystem('d3', IndepVarComp('design_z', 0.5))
model.add_subsystem('comp', Test1Comp())
model.connect('d1.design_x', 'comp.design_x')
model.connect('d2.design_y', 'comp.design_y')
model.connect('d3.design_z', 'comp.design_z')
prob.driver = ScipyOptimizeDriver()
prob.driver.options["optimizer"] = 'SLSQP'
prob.driver.options['tol'] = 1e-8
model.add_design_var("d1.design_x", lower=0.5, upper=1.5)
model.add_design_var("d2.design_y", lower=0.5, upper=1.5)
model.add_design_var("d3.design_z", lower=0.0, upper=1.0)
model.add_objective('comp.obj')
model.linear_solver = ScipyKrylov()
model.linear_solver.options['maxiter'] = int(1200)
model.linear_solver.options['restart'] = int(20)
# prob.model.approx_totals()
prob.setup()
prob.run_driver()
print(prob['comp.y'])
print(prob['comp.z'])
Futrthermore, when looking at ExplicitComponent._solve_nonlinear, which is the method calling ExplicitComponent.compute, it appears to me that the natural way of communicating to OpenMDAO that a point is not converging would be to have ExplicitComponent.compute return True. See the source code for the method:
def _solve_nonlinear(self):
"""
Compute outputs. The model is assumed to be in a scaled state.
Returns
-------
boolean
Failure flag; True if failed to converge, False is successful.
float
absolute error.
float
relative error.
"""
super(ExplicitComponent, self)._solve_nonlinear()
with Recording(self.pathname + '._solve_nonlinear', self.iter_count, self):
with self._unscaled_context(
outputs=[self._outputs], residuals=[self._residuals]):
self._residuals.set_const(0.0)
failed = self.compute(self._inputs, self._outputs)
return bool(failed), 0., 0.
In summary, could someone clarify what is the recommended way of handling non-converging computations in ExplicitComponent.compute?
I have looked at your code, and you specified everything the correct way for telling an optimizer that the component could not evaluate the design point. The problem is that scipy.minimize (which is the optimizer underneath theScipyOptimizeDriver) does not know what do do when it hits a failed point (other than raising an exception), and has no way to report a failure back (at least to my knowledge).
However, pyOptSparseDriver can do something when a point fails: it an try progressing again in the gradient direction, but with a smaller stepsize. I took your code, and exchanged the ScipyOptimizeDriver with a pyOptSparseDriver, used the "SLSQP" optimizer in that package, and it worked around that problematic point just fine, reaching what I assume is a good optimum:
[0.69651727]
[-5.]
[2.]
My driver option code looks like this:
prob.driver = pyOptSparseDriver()
prob.driver.options["optimizer"] = 'SLSQP'
prob.driver.opt_settings['ACC'] = 1e-8
If you don't already have pyoptsparse, which is a separate package not maintained by us, you can get it from https://github.com/mdolab/pyoptsparse -- and you can build and install it with:
python setup.py build
python setup.py install
For your other question, I looked around through our code and found that the failure flag return on _solve_nonlinear is never used for anything. So, the only way to communicate a non-converging status to a driver or a higher-level solver is to raise the AnalysisError. Solvers canraise an AE when they don't converge, if "err_on_maxiter" on its options is set to True (the default is False).
As a final note, I think that while our error handling mechanisms are being used, we haven't thought of everything and are always open to suggestions for improvements.

MetaModelUnstructured Component Optimization

I am missing a point on how to get the 'output' out of a metamodel that is being used as a component in the problem.
It is clear the compute part should have an output but how. Below is the simple sin function as a metamodelunstructured component. I tried to modify the samples. But the error is :
File
"C:\Users\ebarlas\AppData\Local\Continuum\anaconda3\lib\site-packages\openmdao\core\group.py",
line 201, in _setup_procs
subsys._setup_procs(subsys.name, sub_comm)
TypeError: _setup_procs() missing 1 required positional argument:
'comm'
import numpy as np
from openmdao.api import Problem, Group, IndepVarComp
from openmdao.api import ScipyOptimizeDriver
from openmdao.api import MetaModelUnStructured, FloatKrigingSurrogate
# Below class syntax is not working
class trig(MetaModelUnStructured):
def setup(self):
self.add_input('x', 0., training_data=np.linspace(0,10,20))
self.add_output('sin_x', 0., surrogate=FloatKrigingSurrogate(),
training_data=.5*np.sin(np.linspace(0,10,20)))
self.declare_partials(of='sin_x', wrt='x', method='fd')
# If I uncomment 4 lines below and comment out the class above it works fine.
#trig = MetaModelUnStructured()
#trig.add_input('x', 0., training_data=np.linspace(0,10,20))
#trig.add_output('sin_x', 0., surrogate=FloatKrigingSurrogate(),
# training_data=.5*np.sin(np.linspace(0,10,20)))
#trig.declare_partials(of='sin_x', wrt='x', method='fd')
prob = Problem()
inputs_comp = IndepVarComp()
inputs_comp.add_output('x', 5)
prob.model.add_subsystem('inputs_comp', inputs_comp)
prob.model.add_subsystem('trig', trig)
prob.model.connect('inputs_comp.x', 'trig.x')
prob.driver = ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'COBYLA'
prob.driver.options['tol'] = 1e-3
prob.driver.options['disp'] = True
prob.model.add_design_var('inputs_comp.x', lower=4, upper=7)
prob.model.add_objective('trig.sin_x')
prob.setup(check=True)
prob.run_driver()
print(prob['trig.sin_x'])
print(prob['trig.x'])
You shouldn't implement the compute function for a MetaModel (outputs are predicted not computed).
See the docs here: http://openmdao.org/twodocs/versions/latest/features/building_blocks/components/metamodelunstructured.html
thanks for the clarification to the question. Note that the error in your updated example is for passing the class definition trig instead of an instance, but after correcting that I can see the problem.
This is a bug in MetaModelUnStructured... this will be fixed shortly.
You are using MetaModelUnstructured component incorrectly, but there is another bug getting in the way first.
The class trig you've defined is not the same thing as the instance named trig in your commented out code. One is a class, the other is an instance. You can't pass a class into add_subsystem.
However, even fixing that problem there is still a bug in MetaModelUnstructured when its sub-classed. We'll get a fix in before OpenMDAO 2.3, but for now the way you've done it in the commented out code will work.

Is there a way to make an IPython Notebook output interactivly create an input and execute it?

I was wondering if I can make an output interactively run a piece of code. So if for example I had a class (parts in pseudo-code):
import numpy as np
class test(object):
def __init__():
self.a = np.random.randn(10)
print ## Interactive Output: Click me to view data array##
def show():
print a
So when I create a class instance it should output some interactive link (maybe in html) or something like that and when I click it, the show() method should be called. However, I have no idea how to achieve that.
You could use the widgets shipped with the notebook (for jupyter they are an independent package).
Something like this could do what you want (Python 3):
from IPython.html import widgets
from IPython.display import display
import numpy as np
class Test(object):
def __init__(self, arraylen):
self.a = np.random.randn(arraylen)
self.button = widgets.Button(description = 'Show')
self.button.on_click(self.show)
display(self.button)
def show(self, ev = None):
display(self.a)
self.button.disabled = True
test = Test(10)
You create a button widget when you initialise the class widgets.Button(description = 'Show')
Attach an event to it button.on_click(self.show)
And display the button display(self.button)
In the show method I included a way to disable the button functionality once the array is showed self.button.disabled = True. You can comment this line if you want to show more times the array.

Resources