How do I combine tf.absolute and tf.square to create the Huber loss function in Tensorflow? - neural-network

To be precise, the loss function that I'm looking for is the squared error when the absolute error is lesser than 0.5, and it is the absolute error itself, when the absolute error is greater than 0.5. In this way, the gradient from the error function doesn't exceed 1 because once the gradient of the squared error function reaches 1, the absolute error function kicks in, and the gradient remains constant at 1. I've included my current implementation below. For some reason, it's giving me worse performance than just the squared error.
fn_choice_maker1 = (tf.to_int32(tf.sign(y - y_ + 0.5)) + 1)/2
fn_choice_maker2 = (tf.to_int32(tf.sign(y_ - y + 0.5)) + 1)/2
choice_maker_sqr = tf.to_float(tf.mul(fn_choice_maker1, fn_choice_maker2))
sqr_contrib = tf.mul(choice_maker_sqr, tf.square(y - y_))
abs_contrib = tf.abs(y - y_)-0.25 - tf.mul(choice_maker_sqr, tf.abs(y - y_)-0.25)
loss = tf.reduce_mean(sqr_contrib + abs_contrib)
train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)
choice_maker_sqr is a column tensor that is one whenever the error is between 0.5 and -0.5. The names are pretty self explanatory.

Here is my implementation of the Huber loss function in python tensorflow:
def huber_loss(y_true, y_pred, max_grad=1.):
"""Calculates the huber loss.
Parameters
----------
y_true: np.array, tf.Tensor
Target value.
y_pred: np.array, tf.Tensor
Predicted value.
max_grad: float, optional
Positive floating point value. Represents the maximum possible
gradient magnitude.
Returns
-------
tf.Tensor
The huber loss.
"""
err = tf.abs(y_true - y_pred, name='abs')
mg = tf.constant(max_grad, name='max_grad')
lin = mg*(err-.5*mg)
quad=.5*err*err
return tf.where(err < mg, quad, lin)

You can use tf.select to implement it in a single call:
err = y - y_
huber_loss = tf.select(tf.abs(err) < 1.0,
0.5 * tf.square(err),
tf.abs(err) - 0.5) # if, then, else

err = tf.subtract(x,y)
huber_loss = tf.where(tf.less(x,y),
tf.sqrt(tf.square(err)),
tf.abs(err))
with tf.Session() as sess:
print(sess.run(tf.reduce_mean(huber_loss)))

Not sure if this is still relevant, but I would like to point it out to those seeking this in the future. The tensorflow research losses script has an implementation of the Huber loss for Object detection (like its implemented in the FasterRCNN paper)
Here's the link to the method

Related

Modeling of a heated pipe in Modelica/Dymola

I'm currently studying chemical engineering and for my Bachelor thesis, I'm supposed to model a heated pipe that can be used in a superheater by connecting two pipes via a heatport together. Even though I made a big effort on understanding how I code correctly in Modelica, my code is still not working and I'm getting pretty desperate.
So the model basically has to be applicable for both fluid water and overheated steam, so just one-phase flow in instationary conditions. Heat transfer is supposed to happen convectively. Also, I neglect pressure losses due to friction in this model.
Here´s my idea of how the model is supposed to work:
I'm pretty much trying to build a model like the one in the MSL, "Dynamic Pipe", just way more easier so that students who work on the same topic are able to understand my code quickly. So I splitted the pipe into a number of nodes n, the first volume being a inlet state, so basically that state does not really belong to the pipe. After that, the balance equations apply. I´m not quite sure about the momentum equations, so any help on them is highly appreciated. Convective heat transfer is defined by the Model "Convection" from the MSL, Thermal.HeatTransfer.Components.
When testing the model with a flow source, a boundary with fixed pressure and a fixed temperature at the wall, I also get the error "Failed to reduce the DAE index" and I have absolutely no idea what that means.
Also, here is my code:
model Pipe_base3
//Import
import Modelica.SIunits.*;
import Modelica.Constants.pi;
replaceable package Medium =
Modelica.Media.Interfaces.PartialTwoPhaseMedium annotation (choicesAllMatching = true);
parameter Integer n=2;
parameter Integer np=1;
// Geometry==================================================================//
parameter Diameter d_pipe = 0.05 "Inner diameter of pipe"
annotation (Dialog(tab="Geometry"));
parameter Length L = 1 "Length of unit"
annotation (Dialog(tab="Geometry"));
parameter Area A_hex = pi * d_pipe * L
"Shell surface of pipe for heat exchange" annotation (Dialog(tab="Geometry"));
parameter Area A_q = (pi/4)*d_pipe^2
annotation (Dialog(tab="Geometry"));
//Initialisation=============================================================//
parameter Medium.Temperature T_start = 403.15 annotation (Dialog(tab="Initialization"));
parameter Medium.SpecificEnthalpy h_start = Medium.specificEnthalpy_pT(p_start, T_start) annotation (Dialog(tab="Initialization"));
parameter AbsolutePressure p_start = Medium.saturationPressure(T_start) annotation (Dialog(tab="Initialization"));
parameter Medium.MassFlowRate m_flow_start = 0.5 annotation (Dialog(tab="Initialization"));
//Temperature, pressure, energy==============================================//
Medium.Temperature T[n+1]( each start=T_start, fixed=false);
Medium.SpecificEnthalpy h[n+1]( each start=h_start, fixed=false);
Medium.AbsolutePressure p[n+1](each start=p_start, fixed=false);
HeatFlowRate Q_flow[n](fixed = false);
Energy U[n](min=0);
Energy KE[n]; //Kinetic Energy
Medium.ThermodynamicState state[n+1];
// Nondimensional Variables + HeatTransfer===================================//
Medium.PrandtlNumber Pr[n](fixed=false);
ReynoldsNumber Re[n](fixed=false);
Real Xi[n];
NusseltNumber Nu[n];
CoefficientOfHeatTransfer alpha[n];
// Thermodynamic properties==================================================//
Medium.SpecificInternalEnergy u[n](fixed=false);
Medium.DynamicViscosity eta[n];
Density rho[n+1];
Medium.SpecificHeatCapacity cp[n];
Medium.ThermalConductivity lambda_fluid[n];
//Segmental properties
Mass ms[n]; //Mass per Segment
MassFlowRate m_flow[n+1]( each start=m_flow_start/np, fixed=false);
Velocity w[n+1](fixed=false);
// Momentum
Force F_p[n];
Momentum I[n];
Force Ib_flow[n];
parameter Boolean init = false;
Modelica.Fluid.Interfaces.FluidPort_a fluidin( redeclare package Medium = Medium, m_flow(start = m_flow_start, min = 0), p(start = p_start))
annotation (Placement(transformation(extent={{-90,-100},{-70,-80}}),
iconTransformation(extent={{-90,-100},{-70,-80}})));
Modelica.Fluid.Interfaces.FluidPort_b fluidout( redeclare package Medium = Medium, m_flow(start = -m_flow_start, max = 0), p(start = p_start), h_outflow(start=h_start))
annotation (Placement(transformation(extent={{70,-100},{90,-80}}),
iconTransformation(extent={{70,-100},{90,-80}})));
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a[n] heatport
annotation (Placement(transformation(extent={{-10,60},{10,80}}),
iconTransformation(extent={{-10,60},{10,80}})));
Modelica.Blocks.Interfaces.RealOutput[n] alpha_output annotation (Placement(
transformation(extent={{-100,38},{-140,78}}), iconTransformation(extent={{-100,
38},{-140,78}})));
protected
parameter Volume vn = (A_q * L) / n; //Volume per segment
parameter Real x[n] = linspace((L/n), L, n);
parameter Length length = L/n;
initial equation
for i in 1:(n+1) loop
//h[i] = Medium.specificEnthalpy_pTX(p_start, T_start, {1});
p[i] = p_start;
end for;
equation
//Port equations=============================================================//
fluidout.p = p[n];
//fluidin.p-fluidout.p=p[1]-p[n+1];
fluidout.h_outflow = h[n];
fluidout.m_flow = -m_flow[n+1];
//===========================================================================//
h[1]=inStream(fluidin.h_outflow);
p[1]=fluidin.p;
state[1]=Medium.setState_ph(p[1],h[1]);
T[1]=Medium.temperature(state[1]);
rho[1]=Medium.density(state[1]);
m_flow[1]=fluidin.m_flow/np;
m_flow[1]=A_q*rho[1]*w[1];
for i in 1:(n) loop
// Heatport equations======================================================//
T[i] = heatport[i].T;
Q_flow[i] = heatport[i].Q_flow;
// Momentum Balance =======================================================//
der(I[i]) = Ib_flow[i] - F_p[i];
I[i]=m_flow[i]*length;
Ib_flow[i] = (p[i+1]*w[i+1]*w[i+1] - p[i]*w[i]*w[i])*A_q*np;
F_p[i] = (A_q*p[i+1]-A_q*p[i]);
// Energy Balance=========================================================//
U[i] = ms[i] * u[i];
KE[i] = 0.5*ms[i]*w[i+1]*w[i+1];
der(U[i]+KE[i])=m_flow[i]*(h[i]+0.5*w[i]) - m_flow[i+1]*(h[i+1]+0.5*w[i+1]) + Q_flow[i];
der(rho[i+1])= -((rho[i+1]-rho[i])*w[i+1] + (w[i+1]-w[i])*rho[i+1]); //Konti
ms[i]=vn*rho[i+1];
T[i+1]=Medium.temperature(state[i+1]);
state[i+1] = Medium.setState_ph(p[i+1], h[i+1], 1); //Sets thermodynamic state from which other properties can be determined
u[i] = Medium.specificInternalEnergy(state[i+1]);
cp[i] = Medium.specificHeatCapacityCp(state[i+1]);
rho[i+1] = Medium.density(state[i+1]);
eta[i] = Medium.dynamicViscosity(state[i+1]);
lambda_fluid[i] = Medium.thermalConductivity(state[i+1]);
Re[i] * eta[i] = (rho[i+1] * abs(w[i+1]) * d_pipe);
Pr[i] *lambda_fluid[i] = (eta[i] * cp[i]);
Xi[i] = (1.8 * log10(abs(Re[i])+1) - 1.5)^(-2);
Nu[i] = ((Xi[i]/8)*Re[i]*Pr[i])/(1+12.7*sqrt(Xi[i]/8)*((Pr[i])^(2/3)-1))*(1+(1/3)*(d_pipe/x[i])^(2/3));
Nu[i] = Modelica.Fluid.Pipes.BaseClasses.CharacteristicNumbers.NusseltNumber(alpha[i], d_pipe, lambda_fluid[i]);
alpha_output[i] = alpha[i] * (A_hex/n);
m_flow[i+1] = A_q * w[i+1] * rho[i+1];
// der(p[i]) = - w[i]*der(w[i]) * rho[i];
// 0 = m_flow[i-1] - m_flow[i];
// der(rho[i]) = -((rho[i]-rho[i-1])*w[i] + (v[i]-v[i-1])*rho[i]);
//m_flow[i] = A_q * w[i] * rho[i]; //Calculation of flow velocity
//ms[i] = vn * rho[i]; //Mass per segment
//Calculation of thermodynamic properties for each segment=================//
//Heat Transfer============================================================//
end for;
fluidin.h_outflow = h[1]; //
annotation (Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},
{100,100}}), graphics={Line(
points={{-80,-80},{-80,94},{-80,100},{0,20},{80,100},{80,-80}},
color={0,0,255},
smooth=Smooth.None), Line(
points={{-60,-60},{-60,-48},{-60,0},{60,0},{60,-60},{48,-40},{72,-40},
{60,-60}},
color={0,0,255},
smooth=Smooth.None)}), __Dymola_selections);
end Pipe_base3;
Thank you so much in advance!
I was in the same situation when I started using Modelica: I wanted the features of Modelica.Fluid.Pipes.DynamicPipe but with less complexity (I wanted the code to be more readable and less hierarchical). So, like you, I started building my own pipe model from scratch. However, because I wanted to be able to replace the pressure drop and heat transfer correlations and have great flexibility I ended up with a model of nearly the same complexity as Modelica.Fluid.Pipes.DynamicPipe.
My recommendation to you is to
build your own simple dynamic pipe model without any complex
features. This will only be usable for educational purposes (e.g.
letting other students understand your coding principles)
learn how to use Modelica.Fluid.Pipes.DynamicPipe for problems where you need vary model complexity (number of segment, replaceable pressure drop and heat transfer methods etc.). Modelica.Fluid.Examples.HeatExchanger is an example of how you can use Modelica.Fluid.Pipes.DynamicPipe to model a heat exchanger like the one you request.
Here I've shared an example of a very simple dynamic pipe that can be used as a heat exchanger. The pipe is made from n pipe segments and takes advantage of the fact that you can instantiate an array of components and connect the elements in a for loop.
As for the momentum balance, the correct/complete way is to account for the change in momentum by summing all the forces acting on each control volume (Newton's Second law). However, in most lumped models a steady-state momentum balance is adequate which reduces the equation to a linear or quadratic relation between mass flow rate and pressure drop. Modelica.Fluid.Pipes.DynamicPipe has a number of different presssure/flow correlations to choose from.
Best regards,
Rene Just Nielsen
I have built a small example/test that uses your model. It should be a very simple application of your model. Unfortunately I get the same error message:
Cannot find differentiation function:
Modelica.Media.Water.IF97_Utilities.waterBaseProp_ph(boundary1.p, pipe_base3_1.h[2], 0, 1)
with respect to time
Index reduction basically means that the model contains equations that have no unknown. This is solved by differentiation of these equations with respect to time (which can happen multiple times). For more information you can check
https://www.inf.ethz.ch/personal/cellier/Lect/NSDS/Ppt/nsds_ppt_engl.html
especially lecture 16 and probably the ones before it :)
Therefore the Modelica tool will have to know how to do this differentiation. For equations this is usually done automatically, but for functions it has to be specified by the developer. It seems this is not done for Modelica.Media.Water.IF97_Utilities.waterBaseProp_ph()
which is why you get the error message.
There are basically two possibilities to solve this problem:
You change your model to get rid of or revise the constraint equation (the one which has no unknown). It should be the one shown in the error message: der(pipe_base3_1.rho[2]) = ...
You add the function for differentiation to the medium (I'm not much into the Fluid/Media so I have no idea how complicated that is, so I would try to go with 1. first). How this can be done is shown in https://modelica.org/documents/ModelicaSpec33Revision1.pdf section 12.7
Here is the code of the example:
model PipeTest
Pipe_base3 pipe_base3_1(redeclare package Medium = Modelica.Media.Water.WaterIF97_R1pT)
annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
Modelica.Fluid.Sources.FixedBoundary boundary(
nPorts=1,
p=100000,
redeclare package Medium = Modelica.Media.Water.WaterIF97_R1pT)
annotation (Placement(transformation(extent={{-60,-40},{-40,-20}})));
Modelica.Fluid.Sources.FixedBoundary boundary1(
nPorts=1,
p=100000,
redeclare package Medium = Modelica.Media.Water.WaterIF97_R1pT)
annotation (Placement(transformation(extent={{60,-40},{40,-20}})));
Modelica.Thermal.HeatTransfer.Sources.FixedHeatFlow fixedHeatFlow[2](Q_flow={0,0})
annotation (Placement(transformation(extent={{-40,20},{-20,40}})));
equation
connect(boundary.ports[1], pipe_base3_1.fluidin) annotation (Line(points={{-40,-30},{-8,-30},{-8,-9}}, color={0,127,255}));
connect(boundary1.ports[1], pipe_base3_1.fluidout) annotation (Line(points={{40,-30},{8,-30},{8,-9}}, color={0,127,255}));
connect(fixedHeatFlow.port, pipe_base3_1.heatport) annotation (Line(points={{-20,30},{0,30},{0,7}}, color={191,0,0}));
annotation (
Icon(coordinateSystem(preserveAspectRatio=false)),
Diagram(coordinateSystem(preserveAspectRatio=false)),
uses(Modelica(version="3.2.2")));
end PipeTest;
Hope this helps...

Evolutionary Algorithm doesn't seem to get any progress

I'm trying to evolutionize values in order to tune them but I feel my code isn't good enough. My biggest problem is that the values are ranged from -.5 to .5 which makes it really hard to follow what came from which parent. (BTW What I'm evolutionizing is weights in neural network)
def mutate_array(self, inher1, inher2):
shape = inher1.shape
random_values = 2 * np.random.rand(*shape) - 1
mutatings = np.random.rand(*shape) < self.entropy
one_chance = (np.random.rand(*shape) <= 0.5)
new_values = np.array(inher2)
new_values[one_chance] = np.array(inher1[one_chance])
new_values[mutatings] += random_values[mutatings]
return new_values
Where inher1 and inher2 are 2 arrays from the parents, and self.entropy is a varialbe changing(also evolutionarily) between 0.05 - 0.2
What I get when I try this is a complete failure.

Matlab Stepinfo Function

S = stepinfo(Y,T,180,'SettlingTimeThreshold',ST) ;
ts=S.SettlingTime;
in this does it mean ts is the time at which |Y-180| becomes less than ( ST/100 )or something else...
in my code though |Y-180| is less than ST/100 but i am getting ts = NAN;
pls help me out
My code:
if ee(end)>160
S = stepinfo(ee,times,180,'SettlingTimeThreshold',0.01);
else
S = stepinfo(ee,times,0.5,'SettlingTimeThreshold',1);
end
settling_time = S.SettlingTime;
end
where 'ee' is an array of values at each 'times'
ee is basically error angle which becomes 180 or 0 after some time..
thanks
From the help:
The response has settled when the error |y(t) - yfinal| becomes
smaller than a fraction ST of its peak value.
This means that it's the fraction of the peak error value, not an absolute threshold - e.g. if your system was something that started at around 30, and eventually rose and settled at near 180 (yfinal = 180), then the max error is 150, and the threshold would be 0.01*150 = 1.5. So it would need to get to 178.5 (180-1.5).
If your system started at 100 and settled at about 180, your max error is 80, and the threshold is then only 0.8, so your value needs to be at 179.2.
Look at what your min(ee) and max(ee) are and then decide on what a sensible threshold is.
EDIT:
If you want to set a fixed threshold you'll have to calculate it on the fly:
desiredthreshold = 1.8 % absolute value, e.g. 0.01*180
maxerror = 180-min(ee); % assuming your values are all between 0 and 180
actualthreshold = 1.8/maxerror; %if your min value is 0 then this goes to 0.01, otherwise it will be larger

Rotation of image manually in matlab

I am trying to rotate the image manually using the following code.
clc;
m1 = imread('owl','pgm'); % a simple gray scale image of order 260 X 200
newImg = zeros(500,500);
newImg = int16(newImg);
rotationMatrix45 = [cos((pi/4)) -sin((pi/4)); sin((pi/4)) cos((pi/4))];
for x = 1:size(m1,1)
for y = 1:size(m1,2)
point =[x;y] ;
product = rotationMatrix45 * point;
product = int16(product);
newx =product(1,1);
newy=product(2,1);
newImg(newx,newy) = m1(x,y);
end
end
imshow(newImg);
Simply I am iterating through every pixel of image m1, multiplying m1(x,y) with rotation matrix, I get x',y', and storing the value of m1(x,y) in to `newImg(x',y')' BUT it is giving the following error
??? Attempted to access newImg(0,1); index must be a positive integer or logical.
Error in ==> at 18
newImg(newx,newy) = m1(x,y);
I don't know what I am doing wrong.
Part of the rotated image will get negative (or zero) newx and newy values since the corners will rotate out of the original image coordinates. You can't assign a value to newImg if newx or newy is nonpositive; those aren't valid matrix indices. One solution would be to check for this situation and skip such pixels (with continue)
Another solution would be to enlarge the newImg sufficiently, but that will require a slightly more complicated transformation.
This is assuming that you can't just use imrotate because this is homework?
The problem is simple, the answer maybe not : Matlab arrays are indexed from one to N (whereas in many programming langages it's from 0 to (N-1) ).
Try newImg( max( min(1,newX), m1.size() ) , max( min(1,newY), m1.size() ) ) maybe (I don't have Matlab at work so I can tell if it's gonna work), but the resulting image will be croped.
this is an old post so I guess it wont help the OP but as I was helped by his attempt I post here my corrected code.
basically some freedom in the implementation regarding to how you deal with unassigned pixels as well as wether you wish to keep the original size of the pic - which will force you to crop areas falling "outside" of it.
the following function rotates the image around its center, leaves unassigned pixels as "burned" and crops the edges.
function [h] = rot(A,ang)
rotMat = [cos((pi.*ang/180)) sin((pi.*ang/180)); -sin((pi.*ang/180)) cos((pi.*ang/180))];
centerW = round(size(A,1)/2);
centerH = round(size(A,2)/2);
h=255.* uint8(ones(size(A)));
for x = 1:size(A,1)
for y = 1:size(A,2)
point =[x-centerW;y-centerH] ;
product = rotMat * point;
product = int16(product);
newx =product(1,1);
newy=product(2,1);
if newx+centerW<=size(A,1)&& newx+centerW > 0 && newy+centerH<=size(A,2)&& newy+centerH > 0
h(newx+centerW,newy+centerH) = A(x,y);
end
end
end

Changing Auriotouch Linear scale to logarithmic

I don't know if this is even possible to do, but thought I would ask, I suspect that if it is possible, it would be changed in the - (void) renderFFTToTex routine. Does anybody have any ideas about doing this or other suggestions that they could recommend? Thank you.
To rescale the frequency, we need to scale this parameter:
CGFloat yFract = (CGFloat)y / (CGFloat)(maxY - 1);
which has a value between 0..1, and determines which fft output to take to display on display line y.
To get a logarithmic scale, first do the math: a frequency f (0.1kHz-20kHz) must be displayed on a position log(f). Call the low bound (0.1kHz) L, the high bound (20kHz) H. Then after some math [[skipped]] you get:
yFract = ( exp(yFract*log(H/L)) - 1 ) / ( H/L - 1 );
where you should fill in what you think is the H/L ratio, e.g.
yFract = ( exp(yFract*log(20)) - 1 ) / ( 20 - 1 );
(you should check if 0 gives 0 and 1 gives 1, which is the case)