This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.
some copy about the menu


Class: Aws::Glue::Types::Action
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
Struct
|
|
|
Instance Chain:
self,
::Aws::Structure ,
Struct
|
|
| Inherits: |
Struct
|
| Defined in: | gems/aws-sdk-glue/lib/aws-sdk-glue/types.rb |
Overview
Defines an action to be initiated by a trigger.
Constant Summary
Instance Attribute Summary
-
#arguments ⇒ Hash<String,String>
rw
The job arguments used when this trigger fires.
-
#crawler_name ⇒ String
rw
The name of the crawler to be used with this action.
-
#job_name ⇒ String
rw
The name of a job to be run.
-
#notification_property ⇒ Types::NotificationProperty
rw
Specifies configuration properties of a job run notification.
-
#security_configuration ⇒ String
rw
The name of the
SecurityConfiguration
structure to be used with this action. -
#timeout ⇒ Integer
rw
The
JobRun
timeout in minutes.
Instance Method Summary
::Aws::Structure
- Included
| #to_hash | Alias for Structure#to_h. |
Instance Attribute Details
#arguments ⇒ Hash
<String
,String
> (rw)
The job arguments used when this trigger fires. For this job run, they replace the default arguments set in the job definition itself.
You can specify arguments here that your own job-execution script
consumes, as well as arguments that ::Aws::Glue
itself consumes.
For information about how to specify and consume your own Job
arguments, see the Calling ::Aws::Glue
APIs in Python topic in the
developer guide.
For information about the key-value pairs that ::Aws::Glue
consumes to set
up your job, see the Special Parameters Used by Glue topic in
the developer guide.
# File 'gems/aws-sdk-glue/lib/aws-sdk-glue/types.rb', line 76
class Action < Struct.new( :job_name, :arguments, :timeout, :security_configuration, :notification_property, :crawler_name) SENSITIVE = [] include Aws::Structure end
#crawler_name ⇒ String
(rw)
The name of the crawler to be used with this action.
# File 'gems/aws-sdk-glue/lib/aws-sdk-glue/types.rb', line 76
class Action < Struct.new( :job_name, :arguments, :timeout, :security_configuration, :notification_property, :crawler_name) SENSITIVE = [] include Aws::Structure end
#job_name ⇒ String
(rw)
The name of a job to be run.
# File 'gems/aws-sdk-glue/lib/aws-sdk-glue/types.rb', line 76
class Action < Struct.new( :job_name, :arguments, :timeout, :security_configuration, :notification_property, :crawler_name) SENSITIVE = [] include Aws::Structure end
#notification_property ⇒ Types::NotificationProperty (rw)
Specifies configuration properties of a job run notification.
# File 'gems/aws-sdk-glue/lib/aws-sdk-glue/types.rb', line 76
class Action < Struct.new( :job_name, :arguments, :timeout, :security_configuration, :notification_property, :crawler_name) SENSITIVE = [] include Aws::Structure end
#security_configuration ⇒ String
(rw)
The name of the SecurityConfiguration
structure to be used with
this action.
# File 'gems/aws-sdk-glue/lib/aws-sdk-glue/types.rb', line 76
class Action < Struct.new( :job_name, :arguments, :timeout, :security_configuration, :notification_property, :crawler_name) SENSITIVE = [] include Aws::Structure end
#timeout ⇒ Integer
(rw)
The JobRun
timeout in minutes. This is the maximum time that a job
run can consume resources before it is terminated and enters
TIMEOUT
status. The default is 2,880 minutes (48 hours). This
overrides the timeout value set in the parent job.
# File 'gems/aws-sdk-glue/lib/aws-sdk-glue/types.rb', line 76
class Action < Struct.new( :job_name, :arguments, :timeout, :security_configuration, :notification_property, :crawler_name) SENSITIVE = [] include Aws::Structure end


Team
We waited until we could do it right. Then we did! Instead of creating a carbon copy.

Contact
We waited until we could do it right. Then we did! Instead of creating a carbon copy.
Responsive
Your website works on any device: desktop, tablet or mobile.
Customizable
You can easily read, edit, and write your own code, or change everything.

Clean Code
You can find our code well organized, commented and readable.
Documented
As you can see in the source code, we provided a comprehensive documentation.
Free Updates
When you purchase this template, you'll freely receive future updates.


CreatePersonActivity()
This activity provides the UI for adding a new person from the database, with a guided format.
To edit an existing person, EditPersonActivity should be used, not this.
When the user adds all the information and confirms, the data for the new person will be written to the database, and the newly created Person will be sent back to the activity from which this was started as a result.
See Also


Job Listings for Added Courses
Lead Data Engineer
Data Engineer
Applications Sytems Analyst II
Lead Data Engineer
Thorough understanding of popular data warehouse data structures (e.g., star, snowflake) Ability to use tools to introspect...Lead Data Engineer Cornell University is one of the leading research universities in the world. Established in 1865...
Read more 🡢Added Courses
Object-Oriented Programming and Data Structures
Statistical Theory and Application in the Real World


CommunAbility provides post-secondary students with disabilities access to mentorship opportunities through our e-mentorship program.
CommunAbility offers educational information and resources through our webinar and podcast series, learning modules, and a resource library.
CommunAbility promotes positive and empowered identities for students with disabilities through our digital narratives and profile series, peer-to-peer support forums.
CommunAbility
PO Box 365 Toronto Adelaide
Toronto ON
M5C 2K5
<EMAIL_ADDRESS>Phone:<PHONE_NUMBER> ext. 4736


PHYSICS VIVA QUESTION
CAREY FOSTER BRIDGE
It was invented by George Carey Foster
Q1.What is resistance?
A.Resistance R=V \ I, where V is the potential difference applied across the wire and I is the current flowing through it due to the potential difference.
Q2.What is specific resistance?
A.Specific resistance of a material is the resistance of one centimeter length of wire whose cross-sectionalarea is one square centimeter.
Q3.What is the effect of temperature on resistance?
A.Resistance increases with increase in temperature of the material of wire.
Q4.In what materials the resistance decreases with increase in temperature?
A.In Semiconductors
Q5. If the radius of wire is doubled will the specific resistance change?
A.Specific resistance is independent of length or radius of wire it only depends on the material of the wire.
Q6.Why is the resistance wire wire doubled before winding over the bobbin?
A.To avoid the inductive effects. The direction of current in one wire is opposite to the other hence the total flux is always zero.
Q7.What is the principle of Carey Foster Bridge?
A.Position of null point changes on the wire when the resistance is connected in the outer gaps is interchanged.The difference in the value of resistance is equal to the resistances of the differences of bridge wire i.e (L-l).
Q8.What is the principle of Wheatstone Bridge?
A.When the four resistances P,Q,R,S in the four arms of the Wheatstone bridge are such that there is no deflection in the galvanometer, we have:
P/Q=R/S
Q9.When is Carey Foster Bridge most sensitive?
A.It is most sensitive when P,Q,R,S are same or of the same order.
Q10.Why the resistance for inner ratio arms be equal?
A.For increased sensitivity and accuracy.
Q11.What is the minimum difference in resistances that can be measured by Carey Foster Bridge?
A.The resistance of one millimeter length of bridge wire.


barkmark
A modular, progressive Markdown editor. Originally based off of the
woofmark editor
# Markdown? Here's a teensie bit of [Markdown][1] to get you started. Markdown lets you produce **rich** HTML-formatted text by writing _plain text_. You can write `code`, text in _italics_ or give them **a "bolder" format**. You can create headings by prefixing them with one or more hash characters _(#)_. The _less hashes_ they have, the _more prominent_ your headings become. Creating **links** is merely a matter of [wrapping some text in brackets][2] and referencing a resource locator, like the ones you'll find at the bottom of this text. Images can be embedded just the same, except you'll have to prefix the wrapped text with _an exclamation mark_. > Don't forget your towel! > > -- Arthur Dent Note that, ```js var markTags = 'still work'; var within = true; function code (here, are, some, args) { // do wonderful things! return here * are - some + args; } ``` [1]: http://daringfireball.net/projects/markdown/ "Original introduction to Markdown" [2]: http://ponyfoo.com


Toggle navigation
FHIR Simple Demo Application
Dashboard
Modules
Patients
Practitioners
Encounters
Appointments
Claims
Conditions
Allergies
API Documentation
Dashboard
▶ Patients
Practitioners
Encounters
Appointments
Claims
Conditions
Allergies
Resource: Patient
Source: InterSystems IRIS FHIR API
Related Resources
Conditions
Allergies
Encounters
Appointments
Claims


You need to be logged in to place an application
Create job-application
Years of experience in the area:
Your Application
Expertise:
Years of experience:
Availability period:
-
Hand in application
Cancel


Deletes a custom format from the list of formats shown in the Custom Types tab in the Chart Type dialog box.
Syntax
DELETE.CHART.AUTOFORMAT(name_text)
Name_text is the template name you want to delete from the list of custom templates.
Related Function
ADD.CHART.AUTOFORMAT Adds a custom template
Return to index


[§5-21] State dance. Hula is adopted, established, and designated as the official dance of the State. [L 1999, c 83, §2]


All projects in this portfolio have been completed by members of team 3. These projects showcase our team's skills and portray how we have adapted to the new technology based on what we learned as a part of cohort 2 at John Jay's CUNY Tech Talent Pipeline Residency Program.
Grayscale is open source and MIT licensed. This means you can use it for any project - even commercial projects! Download it, customize it, and publish your website!
An example of where you can put an image of a project, or anything else, along with a description.
Another example of a project with its respective description. These sections work well responsively as well, try this theme on a small screen!


DataSpread
File
New
Open
Rename
Delete
Close
Import
Link
Edit
Undo
Redo
View
Formula Bar
Freeze Row
UnFreeze Row
Insert
Picture
Charts
Pie Chart
Help
Exploration Tools
Explore
Hierarchical Column
Sort
Register
Sign In
Paste
Arial
Microsoft Yahei
Times Roman
8
10
30
Merge
Create Table
Select area
Apply function
Toggle Dropdown
Mean
Maximum
Minimum
More
Home
Navigation History
x
Start Explore!
x
Hierarchical form
Show result by
Raw Value
Chart
Add
Remove
Done
Sort
×
Add
Remove
OK
Add a new sheet


1.1 History - Reference Documentation
Authors: Sandro Martini, originally developed by Vaclav Pech and Domingo Suarez Torres
Version: 2.11.6
1.1 History
History
- May 2015
- 2.11.6 release
- Updated to Scala-2.11.6
- Updated to ScalaTest-2.2.3 (in test webapps)
- Reverted last cleanup here
- May 2015
- 2.10.5 release
- Updated to Scala-2.10.5 (latest and probably last in 2.10.x line)
- Updated to ScalaTest-2.2.3 (in test webapps)
- Reverted last cleanup here
- January 2015
- 2.11.5 release
- Updated to Scala-2.11.5
- Updated to ScalaTest-2.2.3 (in test webapps)
- November 2014
- 2.11.4 release
- Updated to Scala-2.11.4
- Updated to ScalaTest-2.2.2 (in test webapps)
- August 2014
- 2.11.2 release
- Updated to Scala-2.11.2
- Updated to ScalaTest-2.2.1 (in test webapps)
- July 2014
- <IP_ADDRESS> release
- Stay on Scala-2.10.4
- Fix tests with Grails-2.4
- April 2014
- 2.10.4 release
- Updated to Scala-2.10.4
- Updated to Grails-2.2.5
- Add some Scala code as a sample (but only in plugin sources, and in the test webapp) and show its usage
- Add ScalaService to get some info on Scala available by the plugin
- December 2013
- 0.10.3 release
- Updated to Scala-2.10.3
- First release for Grails-2.2.x
- December 2013
- 0.10.2 release
- Updated to Scala-2.10.2 (the same used by Akka-2.2.3)
- Last release for Grails-2.0.x
- Small updates/cleanup
- September 2013
- 0.9.2 release
- Updated Scala to 2.9.2
- My first version (took ownership of the plugin, thanks to the original author), with some cleanup of plugin (removed unnecessary files, and other small adjustments)
- November 2011
- 0.6.4 release
- Updated to Scala 2.9.1
- Bug-fix release - http://jira.grails.org/browse/GPSCALA-1
- Done by plugin original author
- Past Releases (Done by plugin original author)
- 0.6.3
- Updated the Scala dependency to 2.9.1
- 0.6.2
- Updated the Scala dependency to 2.9.0-1
- Optimized the compilation process to be faster
- 0.6.1
- Updated the Scala dependency to 2.9.0
- 0.6
- Updated the Scala dependency to 2.8.1
- 0.3
- Polish and documentation
- 0.2
- Bundled Scala 2.7.3 distribution
- Ability to switch between SCALA_HOME and the bundled Scala distribution
- Optional automatic copy of Scala run-time libs into the project's lib folder after compilation
- 0.1
- initial


THIS DEMO WORKS ONLY IN BROWSER THAT SUPPORTS FETCH. Adjust the fetch call to use a different AJAX HTTP request to use it in other browsers.


THE PRINCESS DIARIES A film review by Steve Rhodes Copyright 2001 Steve Rhodes RATING (0 TO ****): ***
Disney's THE PRINCESS DIARIES, directed by Garry Marshall (RUNAWAY BRIDE and PRETTY WOMAN), is a charming, G-rated throwback to a more innocent time at the cinema, when movies were filled with humor that the whole family could laugh at without a trace of embarrassment.
A MY FAIR LADY type of story, it stars Anne Hathaway ("Get Real") as someone with the girlish awkwardness of a Haley Mills and the childlike beauty of a Sandra Dee. As 15-year-old Mia Thermopolis, Hathaway plays a high school student who is a card-carrying member of her school's out-crowd. With her save-the-whales buddy, Lilly Moscovitz, played blandly by Heather Matarazzo, Mia feels disdain for the school's inner circle. Except, that is, for Josh Bryan (Erik von Detten), with whom Mia dreams of sharing her first romantic kiss. But with frizzy hair so thick that it literally breaks hairbrushes, she is unlikely to ever be noticed by a popular jock like Josh.
Mia, who lives with her artist mother (Caroline Goodall) in San Francisco, gets a visit one day from her paternal grandmother, whom she has never met. The grandmother, Queen Clarisse Renaldi (Julie Andrews), explains that Mia's dead father was a prince and that, being the only one left of royal blood, Mia is the only one who can rule their small European kingdom. "Shut up!" a stunned Mia replies. The queen's limo driver and right-hand man, Joe (Hector Elizondo), has to explain that girl meant the reply as an expression of surprise and not a literal command.
Rather than looking upon this opportunity as every girl's dream, Mia resists the chance to wear a crown. "I'm not ready to be a princess," she tells the queen. "I'm still waiting for normal body parts to arrive."
Much of the humor, of course, comes from Mia's training and transformation from nerdish teen to elegant young woman. With a gift for physical comedy, Hathaway manages to make even the most clichéd pratfalls fresh and delightful. Beauty expert Paolo (Larry Miller), who is called in to fix Mia's looks, tells her, "If Brooke Shields had married Groucho Marx," their child would have had her eyebrows. Once he finishes his magic, of course, it is a "wow" moment for the queen and the audience.
For some reason, cinematographer Karl Walter Lindenlaub chose to light the movie harshly and brightly when a hazier glow would seem to have been a better choice for this royal fairly tale. His choice gives the images more of a matter-of-fact look than a magical one.
This sweet confection of a film goes down easily and is filled with many big laughs. It may not be the summer's most memorable movie, but it is a completely entertaining one. Most amazingly, it is a comedy for the whole family with a refreshing absence of bathroom humor. You can take your 5-year-old and her great-grandmother, and they'll both enjoy the picture just as much as you do.
THE PRINCESS DIARIES runs about 1:40. It is rated G and is fine for all ages.
My son Jeffrey, age 12, gave the film ** 1/2. Although he thought it was funny, he said that he didn't like it as much as many other summer movies. His friend Maxim, age 12, gave it *** 12, mentioning how funny and imaginative it was. His friend Sam, age 12, gave it ****, commenting that it was a very funny movie and a real crowd pleaser.
The film opens nationwide in the United States on Friday, August 3. In the Silicon Valley, it will be showing at the AMC and the Century theaters.
Web: http://www.InternetReviews.com Email<EMAIL_ADDRESS>Want free reviews and weekly movie and video recommendations via Email? Just send me a letter with the word "subscribe" in the subject line.
========== X-RAMR-ID: 28969 X-Language: en X-RT-ReviewID: 238955 X-RT-TitleID: 1109228 X-RT-SourceID: 703 X-RT-AuthorID: 1271 X-RT-RatingText: 3/4
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


This is my First Article
Bacon ipsum dolor amet salami ribeye strip steak beef. Jerky alcatra biltong chuck. Fatback filet mignon short loin, jowl spare ribs meatball chuck ham sirloin beef shank ground round turducken biltong. Tri-tip jerky ground round beef chuck short ribs turkey prosciutto, meatball sausage. Spare ribs shoulder drumstick, ball tip cow porchetta burgdoggen alcatra ribeye biltong. Pork chop tenderloin chicken, rump short ribs ribeye salami beef shankle doner swine frankfurter meatloaf pork loin.
Bacon ipsum dolor amet salami ribeye strip steak beef. Jerky alcatra biltong chuck. Fatback filet mignon short loin, jowl spare ribs meatball chuck ham sirloin beef shank ground round turducken biltong. Tri-tip jerky ground round beef chuck short ribs turkey prosciutto, meatball sausage. Spare ribs shoulder drumstick, ball tip cow porchetta burgdoggen alcatra ribeye biltong. Pork chop tenderloin chicken, rump short ribs ribeye salami beef shankle doner swine frankfurter meatloaf pork loin.
Bacon ipsum dolor amet salami ribeye strip steak beef. Jerky alcatra biltong chuck. Fatback filet mignon short loin, jowl spare ribs meatball chuck ham sirloin beef shank ground round turducken biltong. Tri-tip jerky ground round beef chuck short ribs turkey prosciutto, meatball sausage. Spare ribs shoulder drumstick, ball tip cow porchetta burgdoggen alcatra ribeye biltong. Pork chop tenderloin chicken, rump short ribs ribeye salami beef shankle doner swine frankfurter meatloaf pork loin.


FileTargetConfig
public struct FileTargetConfig
Undocumented
-
Undocumented
Declaration
Swift
public static let defaultMaxFileSizeInBytes: UInt64
-
Undocumented
Declaration
Swift
public static let defaultDateTimeFormat: String
-
Log file extension. Defaults to
log
.Declaration
Swift
public let fileExtension: String
-
Log file name. Defaults to
file
.Declaration
Swift
public let fileName: String
-
Maximum number of archived files to keep. Defaults to 1.
Declaration
Swift
public let maxArchivedFilesCount: UInt16
-
Determines minimum time until log file should be archived.
Declaration
Swift
public let archiveFrequency: TimeSpan
-
Determines minimum file size until log file should be archived.
Declaration
Swift
public let maxFileSizeInBytes: UInt64
-
Minimum log levlel to be logged.
Declaration
Swift
public let level: LogLevel
-
Determines logging style used by the target.
Declaration
Swift
public let style: Style
-
Format to be used for log line timestamps.
Declaration
Swift
public let dateTimeFormat: String
-
Optional header to be addead as the first content to newly create log file.
Declaration
Swift
public let header: String?
-
init(fileName:
fileExtension: maxArchivedFilesCount: archiveFrequency: maxFileSizeInBytes: dateTimeFormat: level: style: header: ) Undocumented
-
Undocumented
Declaration
Swift
public var fullFileName: String { get }
-
Undocumented
Declaration
Swift
public var archiveFileName: String { get }


# Copyright 2020 The Flax Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Lint as: python3
"""NN base modules for JAX."""
import abc
import contextlib
import functools
import hashlib
import inspect
from typing import Any
import warnings
from . import utils
from . import stochastic
from flax import jax_utils
from flax import serialization
from flax import struct
import jax
from jax import random
_module_stack = utils.CallStack()
_module_output_trackers = utils.CallStack()
_state_stack = utils.CallStack()
def _track_outputs(x):
for module_output_tracker in _module_output_trackers:
xs = module_output_tracker.retrieve(default=[])
xs.append(x)
module_output_tracker.store(xs)
class _ModuleFrame:
"""A ModuleFrame the context needed to init or apply a Module.
In particular, `self.params` is a dictionary where parameters are
stored (during module init) and read from (during module application).
When `module.init()` is first called, a new ModuleFrame is created with
an empty `params` dictionary. When `self.param` is called within that
module, a new key is added to track that parameter, with the computed
parameter's initial value.
When a module calls into a submodule, a new key is added, with a value
being an empty dictionary. Then that new dictionary is passed in as `params`
on a new sub-ModuleFrame. That new sub-ModuleFrame keeps track of its parent
with the `parent` attribute.
When the whole init process is complete, the top-level ModuleFrame'
`params` are returned, which contain a nested dictionary of parameters.
During module application, a similer process happens but this time
the parameters are only read from.
Additional attributes on ModuleFrame track context needed to assist error
handling, shared parameters and transparent modules that are wrapped without
creating additional sub-parameters. TODO: Consider elaborating on this
last paragraph.
"""
def __init__(self, name,
parent=None, params=None, rng=None,
transparent=False):
if params is None:
params = {}
self.parent = parent
self.rng = rng
self.params = params
self.shared = {}
self.shared_names = set()
self.name = name
self.transparent = transparent
self._name_counter = 0
@property
def is_init(self):
return self.rng is not None
@property
def path(self):
"""Path of the the module scope.
paths are similar to unix file names (eg. '/module/nested/dense')
Returns:
The path of this Module scope.
"""
if self.parent is None:
if self.name is None:
return '/'
else:
return '/' + self.name
path = self.parent.path
if not self.parent.transparent:
if path[-1] != '/':
path += '/'
path += self.name
return path
def is_descendent_of(self, frame):
"""Check whether this frame is a descendent of the given frame."""
if frame is self.parent:
return True
elif self.parent:
return self.parent.is_descendent_of(frame)
else:
return False
def create_name(self):
name = str(self._name_counter)
self._name_counter += 1
return name
def module_method(fn):
"""Decorates a function as a module method.
The `module_method` allows modules to have multiple methods that make use of
the modules parameters.
Example::
class MyLinearModule(nn.Module):
def apply(self, x, features, kernel_init):
kernel = self.param('kernel', (x.shape[-1], features), kernel_init)
return jnp.dot(x, kernel)
@nn.module_method
def apply_transpose(self, x, **kwargs):
kernel = self.get_param('kernel')
return jnp.dot(x, kernel.transpose((1, 0)))
A module method can be called on A Model instance directly::
y, initial_params = MyLinearModule.init(rng, x)
model = nn.Model(MyLinearModule, initial_params)
z = model.apply_transpose(y)
Module methods can also be called on shared modules::
class AutoEncoder(nn.module):
def apply(self, x, features):
linear_fn = MyLinearModule.shared(features=features)
h = linear_fn(x)
y = linear_fn.apply_transpose(h)
return y
Args:
fn: the function to be decorated
Returns:
the decorated function
"""
cache = {}
# module method are just Module class instances.
# But we want it to inherit from the class such that we can call other methods
# of the module. We need a class property to find out which class the method
# is defined on.
def wrapper(cls):
if cls not in cache:
class ModuleMethod(cls):
apply = fn
ModuleMethod.__name__ = fn.__name__
ModuleMethod.__qualname__ = f'{cls.__qualname__}.{fn.__name__}'
cache[cls] = ModuleMethod
return cache[cls]
return utils.classproperty(wrapper)
def _fn_parameters(fn):
return tuple(inspect.signature(fn).parameters.values())
MODULE_CLASSMETHODS = [
'create', 'create_by_shape', 'init', 'init_by_shape', 'call', 'partial'
]
class _ModuleMeta(abc.ABCMeta):
"""Meta class for automatically setting the doc of Modules."""
def __init__(cls, name, bases, attrs):
super(_ModuleMeta, cls).__init__(name, bases, attrs)
apply_fn = cls.apply
apply_doc = apply_fn.__doc__
cls.__doc__ = apply_doc
apply_params = _fn_parameters(apply_fn)
cls.__signature__ = inspect.signature(cls).replace(
parameters=apply_params[1:])
if not bases:
return # skip method signature overides for Module class.
def wrap_special_method(name):
"""override the signature and docstring for one of Module's classmethods."""
orig_fn = getattr(Module, name)
@functools.wraps(orig_fn)
def wrapper(class_, *args, **kwargs):
super_fn = getattr(super(cls, class_), name)
return super_fn(*args, **kwargs)
wrapper.__doc__ = f'''{orig_fn.__doc__}
Apply docstring:
{apply_doc}
'''
base_params = tuple(x for x in _fn_parameters(orig_fn)
if x.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD)
new_params = base_params + apply_params[1:]
wrapper.__signature__ = inspect.signature(orig_fn).replace(
parameters=new_params)
setattr(cls, name, classmethod(wrapper))
for name in MODULE_CLASSMETHODS:
wrap_special_method(name)
def _fold_in_str(rng, data):
"""Fold a string into a jax.random.PRNGKey using its SHA-1 hash."""
m = hashlib.sha1()
m.update(data.encode('utf-8'))
d = m.digest()
hash_int = int.from_bytes(d[:4], byteorder='big')
return random.fold_in(rng, hash_int)
class Module(metaclass=_ModuleMeta):
"""Functional modules."""
def __new__(cls, *args, name=None, **kwargs):
if not _module_stack:
raise ValueError('A Module should only be instantiated directly inside'
' another module.')
parent = cls._get_construction_frame()
apply_kwargs = cls._extend_kwargs(kwargs)
if name is None:
name = cls._default_name()
elif cls._is_shared():
raise ValueError('Cannot override the name of a shared module')
if name is None: # also no default name
name = cls.__name__ + '_' + parent.create_name()
cls._check_name(name, parent)
if parent.is_init and name not in parent.params:
rng = _fold_in_str(parent.rng, name)
params = {}
parent.params[name] = params
else: # apply
if name not in parent.params:
raise ValueError(f'No module named {name} was created during'
' initialization.')
params = parent.params[name]
rng = None
frame = _ModuleFrame(name, parent=parent, rng=rng, params=params,
transparent=cls._is_transparent())
with cls._with_instance(frame) as instance:
y = instance.apply(*args, **apply_kwargs)
_track_outputs(y)
return y
@abc.abstractmethod
def apply(self, *args, **kwargs):
pass
@classmethod
def shared(class_, *, name=None, **kwargs):
"""Partially applies a module and shared parameters for each call.
Args:
name: name of this module.
**kwargs: keyword arguments that should be partially applied.
Returns:
A subclass of Module that shares parameters when called multiple times.
"""
if not _module_stack:
raise ValueError(
'The shared module should be used during Module application')
parent = _module_stack[-1]
if name is None:
name = parent.create_name()
if name in parent.shared_names:
raise ValueError(f'Shared module named "{name}" already exists.')
parent.shared_names.add(name)
partial_module = class_.partial(**kwargs)
class SharedModule(partial_module):
"""Wraps a module to enable shared parameters."""
@classmethod
def _default_name(cls):
return name
@classmethod
def _is_shared(cls):
return True
@classmethod
def _get_construction_frame(cls):
return parent
SharedModule.__name__ = class_.__name__
SharedModule.__qualname__ = class_.__qualname__
return SharedModule
@classmethod
def _get_construction_frame(cls):
"""Return the ModuleFrame where this module was constructed.
Modules can be shared across different parts of a parameter tree.
We need to ensure that the parameter object is the same in every instance
of the same shared module. We resolve this by deciding on a canonical
ModuleFrame (corresponding to a particular part of the top-level parameter
tree) where parameters are stored. Concretely, it is the
"construction frame" -- that is, the frame in which the module is first
defined. For non-shared modules, that's where it's called. For shared
modules, it's where `submodule.shared(...)` is called (which may or may
not be the frame in which it is used.)
Returns:
The ModuleFrame instance where this module was constructed.
"""
return _module_stack[-1]
@classmethod
def partial(class_, *, name=None, **kwargs):
"""Partially applies a module with the given arguments.
Unlike `functools.partial` this will return a subclass of Module.
Args:
name: the name used the module
**kwargs: the argument to be applied.
Returns:
A subclass of Module which partially applies the given keyword arguments.
"""
class PartialModule(class_):
"""Wraps a module with partial application."""
@classmethod
def _default_name(cls):
if name is not None:
return name
else:
return super()._default_name()
@classmethod
def _extend_kwargs(cls, invoke_kwargs):
extended_kwargs = kwargs.copy()
extended_kwargs.update(invoke_kwargs)
return super()._extend_kwargs(extended_kwargs)
# __doc__ is handled by the Module meta class
PartialModule.__name__ = class_.__name__
PartialModule.__qualname__ = class_.__qualname__
return PartialModule
@classmethod
def create(cls, _rng, *args, name=None, **kwargs):
"""Create a module instance by evaluating the model.
DEPRECATION WARNING:
`create()` is deprecated use `init()` to initialize parameters and
then explicitly create a `nn.Model` given the module and initialized
parameters.
Use create_by_shape instead to initialize without doing computation.
Initializer functions can depend both on the shape and the value of inputs.
Args:
_rng: the random number generator used to initialize parameters.
*args: arguments passed to the module's apply function
name: name of this module
**kwargs: keyword arguments passed to the module's apply function
Returns:
A pair consisting of the model output and an instance of Model
"""
warnings.warn("`create()` will be removed soon."
" Use `init()` to initialize parameters and then explicitly"
" create a `nn.Model` given the module and initialized"
" parameters.",
DeprecationWarning)
y, params = cls.init(_rng, *args, name=name, **kwargs)
model = Model(cls, params)
return y, model
@classmethod
def create_by_shape(cls, _rng, input_specs, *args, name=None, **kwargs):
"""Create a module instance using only shape and dtype information.
DEPRECATION WARNING:
`create_by_shape()` is deprecated use `init_by_shape()` to initialize
parameters and then explicitly create a `nn.Model` given the module and
initialized parameters.
This method will initialize the model without computation.
Initializer functions can depend on the shape but not the value of inputs.
Args:
_rng: the random number generator used to initialize parameters.
input_specs: an iterable of (shape, dtype) pairs specifying the inputs
*args: other arguments passed to the module's apply function
name: name of this module.
**kwargs: keyword arguments passed to the module's apply function
Returns:
A pair consisting of the model output and an instance of Model
"""
warnings.warn("`create_by_shape()` will be removed soon."
" Use `init_by_shape()` to initialize parameters and then"
" explicitly create a `nn.Model` given the module and "
" initialized parameters.",
DeprecationWarning)
y, params = cls.init_by_shape(_rng, input_specs, *args, name=name, **kwargs)
model = Model(cls, params)
return y, model
@classmethod
def init(cls, _rng, *args, name=None, **kwargs):
"""Initialize the module parameters.
Args:
_rng: the random number generator used to initialize parameters.
*args: arguments passed to the module's apply function
name: name of this module.
**kwargs: keyword arguments passed to the module's apply function
Returns:
A pair consisting of the model output and the initialized parameters
"""
kwargs = cls._extend_kwargs(kwargs)
if _module_stack:
parent = _module_stack[-1]
else:
parent = None
if name is None:
name = cls._default_name()
frame = _ModuleFrame(name, rng=_rng, parent=parent,
transparent=cls._is_transparent())
with cls._with_instance(frame) as instance:
y = instance.apply(*args, **kwargs)
_track_outputs(y)
return y, cls._post_process_params(frame.params)
@classmethod
def init_by_shape(cls, _rng, input_specs, *args, name=None, **kwargs):
"""Initialize the module parameters.
This method will initialize the module parameters without computation.
Initializer functions can depend on the shape but not the value of inputs.
Args:
_rng: the random number generator used to initialize parameters.
input_specs: an iterable of (shape, dtype) pairs specifying the inputs
*args: arguments passed to the module's apply function
name: name of this module.
**kwargs: keyword arguments passed to the module's apply function
Returns:
A pair consisting of the model output and the initialized parameters
Example:
```
input_shape = (batch_size, image_size, image_size, 3)
model_output, initial_params = model.init_by_shape(jax.random.PRNGKey(0),
input_specs=[(input_shape, jnp.float32)])
```
"""
stochastic_rng = None
try:
stochastic_rng = stochastic.make_rng()
except ValueError:
# Either there is no stochastic scope or the current
# scope is invalid due to another jax transformation.
# In both cases we should not try to lift the stochastic
# scope into the lazy evaluation
pass
def lazy_init(*inputs):
def init_fn():
return cls.init(_rng, *(inputs + args), name=name, **kwargs)
if stochastic_rng is not None:
# Create a new stochastic scope inside the lazy evalution
# this way we can use a stochastic scope in combination
# with init_by_shape.
with stochastic.stochastic(stochastic_rng):
return init_fn()
else:
return init_fn()
return jax_utils.partial_eval_by_shape(lazy_init, input_specs)
@classmethod
def call(cls, params, *args, name=None, **kwargs):
"""Evaluate the module with the given parameters.
Args:
params: the parameters of the module. Typically, inital parameter values
are constructed using `Module.init` or `Module.init_by_shape`.
*args: arguments passed to the module's apply function
name: name of this module.
**kwargs: keyword arguments passed to the module's apply function
Returns:
The output of the module's apply function.
"""
params = cls._pre_process_params(params)
kwargs = cls._extend_kwargs(kwargs)
if _module_stack:
parent = _module_stack[-1]
else:
parent = None
if name is None:
name = cls._default_name()
frame = _ModuleFrame(name, params=params, parent=parent,
transparent=cls._is_transparent())
with cls._with_instance(frame) as instance:
y = instance.apply(*args, **kwargs)
_track_outputs(y)
return y
def param(self, name, shape, initializer):
"""Defines a parameter within the module's apply function.
Args:
name: The name of the parameter.
shape: The shape of the parameter. If None the param be any type.
initializer: An initializer function
taking an RNG and the shape as arguments.
Returns:
The value of the parameter.
"""
frame = self._frame
if frame.is_init:
if name in frame.params:
raise ValueError(
"Name '%s' was already used for another parameter." % name)
key = _fold_in_str(frame.rng, name)
frame.params[name] = initializer(key, shape)
if name not in frame.params:
raise ValueError("Parameter with name '%s' does not exist." % name)
param = frame.params[name]
if shape is not None and param.shape != shape:
raise ValueError(
'Existing shape {} differs from requested shape {}'.format(
param.shape, shape))
return param
def get_param(self, name):
"""Retrieves a parameter within the module's apply function.
Args:
name: The name of the parameter.
Returns:
The value of the parameter.
"""
frame = self._frame
if name not in frame.params:
raise ValueError("Parameter with name '%s' does not exist." % name)
return frame.params[name]
def state(self, name, shape=None, initializer=None, collection=None):
"""Declare a state variable within the module's apply function.
A state variable has an attribute value which can be updated by simply
assigning a value to it. For example::
class Example(nn.Module):
def apply(self, inputs, decay=0.9):
ema = self.state('ema', inputs.shape, initializers.zeros)
ema.value = decay * ema.value + (1 - decay) * inputs
return inputs
By default Modules are stateless. See `flax.nn.stateful` to enable stateful
computations.
Args:
name: the name of the state variable.
shape: optional shape passed to the initializer (default: None)
initializer: optional initializer function
taking an RNG and the shape as arguments.
collection: optional `flax.nn.Collection` used to store the state.
By default the state collection passed to the `nn.stateful` context is
used.
Returns:
An instance of ModuleState.
"""
_top_frame('state')
if collection is None:
collection = get_state()
state = ModuleState(collection, name)
# find the frames that are in init mode
init_frames = [f for f in _module_stack if f.is_init]
if initializer is not None and init_frames:
# use the closest frame that is initializing to get an rng
init_frame = init_frames[-1]
init_frame.rng, key = random.split(init_frame.rng)
init_value = initializer(key, shape)
state.value = init_value
return state
def is_stateful(self):
return is_stateful()
def is_initializing(self):
_top_frame('is_initializing')
return self._frame.is_init
@classmethod
@contextlib.contextmanager
def _with_instance(cls, frame):
"""Private constructor for Module.
A module instance is constructed using a scope and is tied to a _ModuleFrame
This way the methods on the Module instance can rely on the _ModuleFrame
being available.
Args:
frame: an instance of _ModuleFrame
Yields:
An instance of Module
"""
instance = object.__new__(cls)
instance._frame = frame # pylint: disable=protected-access
with _module_stack.frame(frame):
yield instance
@classmethod
def _check_name(cls, name, parent):
"""Check whether the name of the module is valid within the parent scope."""
if name is not None:
if not isinstance(name, str):
raise ValueError('Name must be a string.')
if '/' in name or ':' in name:
raise ValueError('Name should not contain slashes or colons.')
shared = cls._is_shared()
if name in parent.shared:
# a module with this name already exists. Check validity of sharing
if shared != parent.shared[name]:
raise ValueError(f'The name "{name}" is used for both a shared'
' and unshared module.')
if not parent.shared[name]:
raise ValueError(f'A module with named "{name}" already exists.')
parent.shared[name] = shared
@classmethod
def _extend_kwargs(cls, kwargs):
return kwargs
@classmethod
def _pre_process_params(cls, params):
return params
@classmethod
def _post_process_params(cls, params):
return params
@classmethod
def _is_transparent(cls):
return False
@classmethod
def _is_shared(cls):
return False
@classmethod
def _default_name(cls):
return None
def module(fun):
"""Convert a function into the apply method of a new Module.
This is convenient shortcut for writing higher level modules that don't need
access to `self` for creating parameters directly.
Example usage::
@nn.module
def DenseLayer(x, features):
x = flax.nn.Dense(x, features)
x = flax.nn.relu(x)
return x
This is exactly equivalent to defining the following `nn.Module` subclass::
class DenseLayer(nn.Module):
def apply(self, x, features):
x = flax.nn.Dense(x, features)
x = flax.nn.relu(x)
return x
Args:
fun: the function to convert.
Returns:
New Module subclass.
"""
@functools.wraps(fun)
def apply(self, *args, **kwargs):
del self # unused
return fun(*args, **kwargs)
return type(fun.__name__, (Module,), dict(apply=apply))
# TODO(flax-dev) consider removing this...
class TransparentModule(Module):
"""Transparent module.
A transparent module can only have one parameter named '0'.
"""
@classmethod
def _pre_process_params(cls, params):
return {'0': params}
@classmethod
def _post_process_params(cls, params):
entries = list(params.items())
if len(entries) != 1:
raise ValueError('Transparent modules should have exactly one child.')
key, value = entries[0]
if key != '0':
raise ValueError('Transparent module should contain an unnamed child.')
return value
@classmethod
def _is_transparent(cls):
return True
class TruncatedModule(TransparentModule):
"""Wraps a Module and returns the requested intermediate outputs instead.
See `Model.truncate_at` for a simple api to get the intermediate outputs of
an existing Model.
"""
def apply(self, *args, wrapped_module=None, truncate_path=None, **kwargs):
"""Apply the wrapped module and return some of its intermediate outputs.
Args:
*args: the positional arguments for the wrapped module.
wrapped_module: The module class to be wrapped.
truncate_path: the full name of the module (eg. '/module/sub_module').
A list or dict of module paths can be provided to obtain the
intermediate outputs of multiple modules.
**kwargs: the keyword arguments for the wrapped module.
Returns:
The intermediate outputs specified by truncate_path.
"""
if wrapped_module is None or truncate_path is None:
raise ValueError(
'`wrapped_module` and `truncate_path` are required keyword arguments')
with capture_module_outputs() as module_outputs:
wrapped_module(*args, **kwargs, name='0')
def lookup_output(path):
return module_outputs[path]
return jax.tree_map(lookup_output, truncate_path)
@contextlib.contextmanager
def capture_module_outputs():
"""A context manager that captures all model outputs.
Yields:
A `flax.nn.Collection` containing all module outputs.
"""
with Collection().mutate() as module_outputs:
with _module_output_trackers.frame(module_outputs):
yield module_outputs
class ModuleState():
"""Tracks a state variable.
ModuleState instances should not be created directly. See `Module.state` on
how to create state variables inside modules.
"""
def __init__(self, collection, name):
self._collection = collection
self._name = name
def _get_state_dict(self):
state_dict = self._collection.retrieve(default={})
assert isinstance(state_dict, dict)
return state_dict
@property
def name(self):
return self._name
@property
def value(self):
state_dict = self._get_state_dict()
if self._name not in state_dict:
raise ValueError(f'No state variable named `{self._name}` exists.')
return state_dict[self._name]
@value.setter
def value(self, v):
state_dict = self._get_state_dict()
state_dict[self._name] = v
self._collection.store(state_dict)
@contextlib.contextmanager
def stateful(state=None, mutable=True):
"""A context manager for stateful computations.
Module's that use the `Module.state` by default store state inside the
`Collection` specified by the (innermost) `nn.stateful` context manager.
Typically stateful is used in 3 different modes:
1. During init no existing state is available and the stateful context creates
a new state collection.
2. During training the state is passed to `nn.stateful` and the new state
is returned which will contain the updated state.
3. During evaluation the state is passed with `mutable=False` such that the
model can retrieve the state but is not allowed to mutate it.
Example::
class MyModel(nn.Module):
def apply(self, x):
x = nn.Dense(x, 12)
x = nn.BatchNorm(x)
return x
with nn.stateful() as state:
_, initial_params = MyModel.init(rng, x)
model = nn.Model(MyModel, initial_params)
with nn.stateful(state) as new_state:
model(x2)
with nn.stateful(new_state, mutable=False):
evaluate_model(model)
Args:
state: a `flax.nn.Collection` containing the current state.
By default a new collection will be created.
mutable: If true the state will be mutable otherwise it will be frozen.
Yields:
A `flax.nn.Collection` containing the new state.
"""
if state is None:
state = Collection()
if mutable:
with state.mutate() as new_state:
with _state_stack.frame(new_state):
yield new_state
else:
with _state_stack.frame(state):
yield state
def is_stateful():
"""Returns true if a stateful scope is currently active (see `flax.nn.stateful`)."""
return bool(_state_stack)
def get_state():
if not _state_stack:
raise ValueError('Use the flax.nn.stateful context manager to enable'
' stateful computations.')
return _state_stack[-1]
def _top_frame(call_name):
if not _module_stack:
raise ValueError('%s should only be used inside a '
'module\'s apply function.' % call_name)
return _module_stack[-1]
@struct.dataclass
class Model:
"""A Model contains the model paramaters, state and definition."""
module: Module = struct.field(pytree_node=False)
params: Any
def __call__(self, *args, **kwargs):
return self.module.call(self.params, *args, **kwargs)
def truncate_at(self, module_path):
"""Truncate the model by returning the outputs of the given sub-module.
Args:
module_path: the full name of the module (eg. '/module/sub_module').
A list or dict of module paths can be provided to obtain the
intermediate outputs of multiple modules.
Returns:
A new model with the truncated outputs. If module_path is a pytree of
paths the outputs will be have the same structure where each path is
replaced by the corresponding intermediate output.
"""
truncated_module_cls = TruncatedModule.partial(
wrapped_module=self.module, truncate_path=module_path)
return self.replace(module=truncated_module_cls)
def __getattr__(self, name):
value = getattr(self.module, name)
if inspect.isclass(value) and issubclass(value, Module):
def wrapper(*args, **kwargs):
return value.call(self.params, *args, **kwargs)
return wrapper
raise AttributeError(f'No attribute named "{name}".')
def __hash__(self):
# Jax will call hash when model is passed to a function transform.
# the compiled function should not be shared among model instances because
# it closes over the specific parameters of this model instance.
return id(self)
class Collection:
"""A collection of tensors useful for tracking state.
A Collection can be used to associate data with the application of a Module.
For example a collection can be used to collect activations across modules.
Another common use case for collections is to track internal state.
For example, the running averages in BatchNorm can be stored in a collection.
Attributes:
state: the initial state by default an empty collection is created.
"""
def __init__(self, state=None):
if state is None:
state = {}
self.state = state
# The anchor is used to determine the prefix of the collection.
# This way we can create/nest collections inside modules.
self._anchor = _module_stack[-1] if _module_stack else None
self._mutable = False
self._master_level = None
self._root = None
def as_dict(self):
"""Returns a dictionary with module paths as keys and the stored values.
Returns:
The stored values as a dictionary.
"""
return self.state.copy()
def __getitem__(self, key):
return self.state[key]
@contextlib.contextmanager
def mutate(self):
# pylint: disable=protected-access
new_col = jax.tree_map(lambda x: x, self) # clone the collection
new_col._mutable = True
new_col._master_level = utils._trace_level(utils._current_trace())
try:
yield new_col
finally:
new_col._mutable = False
def retrieve(self, default=None):
"""Retrieves a value from the Collection.
This functions should only be called with the apply function of a module.
Args:
default: The default returned when nothing is stored (default: None)
Returns:
The value previously stored in the collection.
"""
_top_frame('retrieve')
path = self._current_path()
return self.state.get(path, default)
def store(self, value):
"""Stores a value in the Collection.
This functions should only be called with the apply function of a module.
Args:
value: The value to be stored in the collection
Returns:
The previous value stored in the collection or None.
"""
frame = _top_frame('store')
if not self._mutable:
raise ValueError('Collection is not mutable. Use the `mutate` method to'
' create a mutable copy.')
# Use the Jax TraceMaster to determine if a Collection is modified from
# inside a nested jax transformation.
# In this case, we throw an error because transforming a stateful function
# is ill-defined (eg. what does vmap of BatchNorm do?).
# TODO(jheek): Add doc guide on combining jax transforms and state.
# TODO(jheek): Should some transformations be excempt from this error?
value_level = utils._level_of_value(value)
if value_level > self._master_level:
raise ValueError('Stateful operations are not allowed when the Collection'
' is created outside of the current Jax transformation')
# The root of a Collection is the first module scope that gets created
# inside the mutate scope of the Collection. By allowing only one unique
# root scope, we guarantee that state is not accidentally shared
# between different models. When a user specifies an explicit name we can
# distinguish models and a collection can have multiple roots.
if frame == self._anchor:
# Example:
# with nn.Collection.mutate() as coll:
# coll.store(1)
raise ValueError('State should be stored from within a module.'
' Consider using the value directly instead of'
' storing it in a Collection.')
if not frame.is_descendent_of(self._anchor):
# edge case where the Collection cannot capture the scope of a shared Module
# See test_collection_store_fails_if_out_of_scope in nn_test.py
raise ValueError('Trying to capture state outside the scope of this Collection.'
' Most likely due to passing around a shared Module.')
root = self._find_root(frame)
if self._root is None:
self._root = root
elif self._root != root:
if self._root.name is None or root.name is None:
# In the following examples, should the two calls to `StatefulModule` share state or not?
# Because it's ambiguous, we throw an error and require the user to explicitly separate state
# by giving each instance a separate name, or to explicitly pass the same name
# in order to share state.
# with nn.statefull(state) as new_state:
# StatefulModule.call(params)
# StatefulModule.call(params2)
raise ValueError('When multiple top-level module calls use a Collection'
' each top-level module should have a name.')
path = self._current_path()
old_value = self.state.get(path, None)
self.state[path] = value
return old_value
def _find_root(self, frame):
"""Find the root frame with respect to the anchor.
The root frame is defined as the child of anchor
that is an ancestor of frame.
The root is used to verify that a Collection does not
have multiple unnamed roots.
Args:
- frame: the frame of which we want to know the root
Returns:
The root of the given frame.
"""
assert frame.is_descendent_of(self._anchor)
root = frame
while root.parent != self._anchor:
root = root.parent
return root
def _current_path(self):
""""The relative path from the currently active module scope to the root of the collection.
For example: If a collection is created in the path '/module/nested' and
something is stored by a module with the path '/module/nested/block/conv'
the key in the collection dict will be '/block/conv'.
Returns:
the relative path of the active module scope.
"""
frame = _module_stack[-1]
assert frame.is_descendent_of(self._anchor)
path = _module_stack[-1].path
if self._anchor is not None and self._anchor.path != '/':
prefix = self._anchor.path
assert prefix == path[:len(prefix)]
return path[len(prefix):]
else:
return path
def iterate_collection(collection):
# jax iterates through pytrees for each argument/return value of a functional
# transformations. When the collection is mutable we throw an error this way
# we avoid silent errors due to impurity of a traced function.
if collection._mutable: # pylint: disable=protected-access
raise ValueError('A mutable collection should not be transformed by Jax.')
meta = (type(collection), collection._anchor) # pylint: disable=protected-access
return (collection.state,), meta
def collection_from_iterable(meta, state):
ty, anchor = meta
coll = ty(state[0])
coll._anchor = anchor # pylint: disable=protected-access
return coll
# make sure a collection is traced.
jax.tree_util.register_pytree_node(Collection,
iterate_collection,
collection_from_iterable)
def _collection_state_dict(collection):
return collection.as_dict()
def _collection_from_state_dict(_, state):
return Collection(state)
serialization.register_serialization_state(
Collection, _collection_state_dict, _collection_from_state_dict)


2 Corinthians 2:13
I had no rest in my spirit, because I found not Titus my brother: but taking my leave of them, I went from thence into Macedonia.


Moment tensor entries represented in spherical coordinates (r-t-p (up-south-east) basis). Six distinct moment tensor entries are used to form 3 x 3 symmetric
tensor in spherical coordinates. These values are used to calculate Strike / Dip / Rake for closest double couple.
Strike, dip, and rake are used to describe earthquake Focal Mechanisms. These values are computed based on moment tensor entries in r-t-p (up-south-east) basis
The code used for 3D moment tensor is based on Carl Tape's work. See
http://www.giseis.alaska.edu/input/carl/ for papers and reference to Mathematica scripts.


TETR.IO isn't free to run, and blocking ads means osk doesn't recieve any revenue. The game includes an option to turn off ads natively, but still loads the ad script. Using TETR.IO PLUS's ad blocker will block this script, preventing it from tracking you. If you block ads, take a moment to consider purchasing TETR.IO Supporter through the in-game menu. If you're already a supporter, great! You should use this anyway because invasive ad scripts. Consider also reading osk's blog post about the addition of ads into the game.
Note: These are links for supporting osk and TETR.IO directly. They do not support the author of TETR.IO PLUS. TETR.IO PLUS will remain freely available without ads.


Now that the slick, sappy "Simon Birch" has almost run its course at the box office there may not be a high desire among moviegoers to see "The Mighty," another story about misfit boys joining forces to survive. But it would be a shame if this funny, warm-hearted film didn't find a sizable audience; it's as captivating as "Simon" is contrived. When Hollywood attempts to portray the jinior-high years, it often opts for a heavily sentimental approach in which everyone is cutely geeky, daydreaming about their first kiss or trying to join a cool clique. The realities of pre-adolescence -- particularly for those kids who, for one reason or another, don't fit in -- are considerably less rosy. If, for example, you're Maxwell Kane (Elden Henson), the slow-witted son of a convicted murderer, you might easily end up getting slammed regularly by peers and adults alike. "Killer Kane, Killer Kane, has a son who's got no brain," chant Max's classmates, while his gym teacher asks if he needs to translate instructions into Neanderthal for Max to understand. Next door to Max lives Kevin Dillon (Kieran Culkin), a brilliant mind trapped in a body crippled and twisted by Morquio's syndrome. His mother (Sharon Stone) encourages Kevin to explore the world of books and science, but she fears letting him explore the world itself. "She's afraid I'll get trampled," Kevin tells Max. "Sometimes I think my mom would like me to stay home with a tube down my throat." Separately, these two aren't making it. United, they're formidable. Kevin shares his intellect with the almost illiterate Max, and Max provides the physical prowess Kevin needs, or, as Max puts it, "he became my brain and I became his feet." But before you write off "The Mighty" as a standard-issue sermonette about sharing, take another look. Surrounding Kevin and Max is a circle of vivid characters, exceptionally well-played by such actors as Harry Dean Stanton, Gena Rowlands, James Gandolfini and, in the film's biggest surprise, an unrecognizable Gillian Anderson as a tart with mall-hair. Daringly, director Peter Chelsom has infused the film with a kind of magical realism that usually functions better on the printed page than it does on the screen. Here, the technique not only works, it gives "The Mighty" that extra flavor that sets it apart from other similar tales. In the eyes of Max and Kevin, Cincinnati is just Camelot in disguise, full of damsels in distress, black-hearted villains and Holy Grails waiting to be discovered. It sounds silly and precious, but Culkin and Henson are so thoroughly convincing they rope us into the fantasy. Stone's performance as a lonely woman living in awe of her child ("Congratulations, Mrs. Dillon: It was a tough delivery, but you've given birth to a healthy seven-pound dictionary," she jokes) is understated and true-to-life. Because of its pro-reading theme and its message about acceptance, "The Mighty" will probably be a big attraction for teachers looking to take their classes on a field-trip, and that's fine. But when pictures are made with as much care and heart as this one was, they deserve to be seen by everyone. Forget "Simon Birch": "The Mighty" is truly something special. James Sanford
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Special Question :
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet, quo!
click me!
Name:
ok
one
two
three
four
------------
Choose a username:
Usernames must be lowercase and 4-8 characters in length.
Submit


If a good artist imitates and a great artist steals, wouldn’t a computer program designed to steal be the greatest artist ever?
Painting in VR, playing video games in AR: the future of art-consumption looks incredibly exciting. But these examples are all rooted in humanity: created for and by humans, a closed loop of foibles, brilliance and stupidity. MONTAG's Sean Fleming asks: what if we left the humans out of the creative process all together?
Talking to yourself
You may have heard that Facebook had to abandon an experiment recently when two artificial intelligence chatbots started communicating with each other in a language they’d created themselves.
The exchange was an attempt to negotiate the trade of items such as balls, books, and hats. The chatbots were successful at trading with one another albeit at the expense of our understanding. The bots had created their own optimised version of English that they understood – but we humans didn’t. Great! Ixnay on the shutting us out of your comms please, Skynet!

As usual, clickbait content had given me unrealistic beauty standards: every publication talking about the bot made it sound like some mad scientists pulling the plug on a dangerously cogent AI poised to destroy everything you care about.
Actually it just wasn’t doing what it was supposed to be doing, so they turned it off. Thanks, Millennial Media. Doin’ it for tha clicks as per usual.
Once I got past these sensationalist headline-driven expectations, I appreciated the fact whatever computational shorthand the AI had used to conduct negotiations, it had created something new from another input.
Think about that for a second.
 I’ve got something better! You could be forgiven for thinking that inter-artificial communication has an air of humanity surrounding it.
It got me thinking: if an AI was perfectly capable of creating something new from human input – with the result requiring some element of interpretation and so was to some extent a creative use of the source material – then AI could quite legitimately create what could be deemed art.
I'm not a caveman, I'm a cave, man
For me there was a striking similarity to our attempts at understanding parietal art.
Cave paintings, AKA Parietal Art, you cultureless oafs. (Picture by Abdullah Geelah - English Wikipedia, CC BY-SA 3.0)
Cave paintings predate written language and it’s widely theorised that they were the way neolithic humans communicated with one another. Of course, there’s nobody left to ask whether that’s really true or not.
But consider how we modern humans try to understand the lives, fears and day-to-day goings-on of a people so far removed from ourselves: could we view early AI to AI comms in the same way?
We can only interpret, and in our attempts to understand, we mythologise Cave Painting. We elevate it to art. Maybe we can do the same for the early communication between chatbot and chatbot.
Because – and stop me if this is getting too cerebral (see also: pretentious) – there is an innate value in language and communication even when we don’t fully, or barely, understand. Take that Damien Hirst!
Of course, once you start bunching this bot-on-bot creative phenomena with human art and crediting it with possessing human qualities things get very interesting indeed. (Protip: it’s still better than Damien Hirst).
Art-ificial
Technology and art have always had a tumultuous – and incestuous - relationship.
Before photography, painters and sculptors strived to create what we might now call photorealistic forms in their own medium. And then mechanically perfect realism – as brought to you by the camera – put representational painting on what we could refer to delicately as indefinite hiatus.
Painting didn’t just stop though, and photography’s influence on painting gave birth to new forms.
MONTAG has discussed before how AI is coming for your cushty job in creative media.
 The machines will be processing backhanded compliments from poseurs pretending to understand what’s on display too.
Like acid, on acid... on acid
Most people’s first experience with algorithmically-etruded art was 2015’s Google DeepDream bonanza.
For the uninitiated: DeepDream was Google’s super trippy neural network that everyone was playing with a few years back. People were drawn to it because it was pretty cool tech, yeah; but I, like many other curious pranksters, pumped images into the bot in the hope that the results would help us relive that time we did acid at Glastonbury, one demented pixel at a time.
Generally, I think people were fascinated by the idea of a computer creating art. For me, one of the most beautiful traits of DeepDream’s work was that, by putting in an image, or music, or film through the bot, whatever it spat out was its attempt to understand the artistic input.
It looked for patterns and shapes the same way humans do. In all the white noise it latched on to stuff it vaguely understood at a very base level, which much like myself is mostly just dogs’ faces and eyeballs.
Crank up the Aphex Twin: we’re going for a ride!
Perhaps as humans, our best route to understanding our arty bot buddies is to collaborate with them on an project - you know, you like you did back in art school with that cute weird foreign exchange student.
And just like back then, hopefully the act of teaming up will lead to a lot more exciting stuff happening, at a much more primal level.
Perfect Harmony
Studies are already suggesting that the future of work will be a sympathetic balance: AI and humans working side-by-side rather than one pushing the other into unplanned obsolescence. Perhaps art will head in the same direction.
One artist using AI to understand his own work and then produce something new off the back of this new perspective is Roman Lipski.
The concept was simple: have a machine learn Lipski’s painting and in doing so give the machine what can only be described as an ‘artistic intelligence’.
Having learnt from Lipski’s paintings, AIR (Artificial Intelligent Roman) created new work using his style and motifs for Lipski to use these new paintings as inspiration for new work. Yeah, exactly.
LILO. Lipski In Lipski Out.
As the first example of an artificial muse it’s a fascinating project, and on a technical level it's a brilliant example of using data and a non-human perspective to better yourself as an artist.
Much like how photography pushed painting into new and exciting realms, the advent of AI-derived artistic produce should make artists - and art - better.
Lipski’s AIR also raises a few interesting questions, the most basic being: if Roman then signs one of these artificially-created paintings, does it become his work, as if he’d created it by his own hand? Why not? How far removed is this from Andy Warhol’s soup can screenprints?
If a good artist imitates and a great artist steals, wouldn’t a computer program designed to steal be the greatest artist ever?
When an artist's work can be fed through a machine that understands it and produces new work to rival the quality of the original, can we program artistic sensibility into it too? And can it then produce its “own” work?
Humans create art to start dialogues, to provoke, to speak. Can something that doesn’t have human-like emotional intelligence ever produce something really worthy of the title art?
If you saw a piece of work in a gallery and the artist that had created it was none other than the RothkoBot 3000, would the cold, silicon mind behind it devalue the work, in your eyes? The work produced an emotional response: does the fleshiness of the creator even matter?
And just think of the investment opportunities: maybe a robot’s art would increase in value every time it gets a firmware update. What if the artwork itself was updated over-the-air every now and then?
AI-produced art triggers so many questions, although not all of them rhetorical, so feel free to whip these out at dinner parties to one-up whoever’s hosting.
Our motto: Artpocolypse Now!
Maybe we should all accept our fate, and get ready to embrace a future where art is better, cheaper, and everywhere.
 Walter Benjamin, eat your heart out.


In the **Data Compression Service** in Bandwidth Hero extension, add `https://your-netlify-domain.netlify.app/api/index`, and you are good to go. For the source and more information go to https://github.com/adi-g15/bandwidth-hero-proxy


Pawsome is a online community where pet lovers can discuss their love of animals. Pawsome provides resources, a public forum, and curated pet content.


Get original and create a Christmas tree with a ladder. Wrap lights around the ladder and decorate with ornaments. The is perfect if you don't have a Christmas tree but still want some decorations.
30-40mins


We host monthly meetups to explore functional programming with Elixir. Join us in the Triangle Devs Slack in the #elixir channel
Jan 14, 2016
Dec 10, 2015
Nov 12, 2015
May 6, 2015


JSONStore Hybrid
Initialize (Login/Open)
Close All (Logout)
Destroy Everything
Remove Collection
Add Data
Find By Name (Fuzzy Search)
Find By Age (Exact Search)
Find All
Find (by id)
Replace (by id)
Remove (by id)
Load Data From Adapter
Get Dirty Documents
Push Changes to Adapter
Count All
Count By Name
Change Password
Add Key/Value Pair
Find Value


&
&
&
We know Alice Paul as the suffragist leader who achieved passage of the 19th Amendment
and authored the original Equal Rights Amendment. But when Paul met Feminists
for Life co-founder Pat Goltz, Paul told Pat that FFL was not the first pro-life
feminist group. Alice Paul said she and other first-wave feminists opposed abortion
too.
The same belief in human rights that inspired abolition became the undulating impulse
that gave birth to feminism.
The first feminists–who had no legal right to vote, testify on their own behalf,
or sit on a jury–affirmed the fundamental liberty of every woman, just as many
had affirmed the fundamental liberty of every enslaved person. Denied the right
to stop marital rape, control their own finances, or (with the exception of Oberlin
College) pursue higher education, the first feminists still found strength to give
voice to the most vulnerable, including born children in need of empowered parents
and unborn children peacefully floating in their mothers’ wombs.
When I first started at Feminists for Life, an opponent of FFL’s emerging voice
alleged we offered only one pro-life quote from one lone suffragist that we kept
repeating over and over again. Famous historians peddled the claim that there was
no documentation of Susan B. Anthony’s opposition to abortion.
But thanks to the late Mary Krane Derr, who was commissioned by the FFL Board of
Directors to research The Revolution (published by Susan B. Anthony and co-edited
by Elizabeth Cady Stanton) and Woodhull and Claflin’s Weekly (published by Victoria
Woodhull and Tennessee Claflin), we established an undeniable consensus among early
feminists against the horror of abortion. Other researchers like Suzanne Schnittman,
Lisa Bellecci-st. romain, and Ruth Moynihan dove deeper, bringing our rich pro-life
feminist history forward into the light.
The early feminists had a spectrum of opinions and pursuits within their movement,
just as we have within pro-life feminism today. Like second wave feminists of the
1970s, many of whom strayed from feminism’s original non-violent tenets, some of
the first wave feminists’ words and actions can be disappointing-even offensive.
Suzanne Schnittman warned me long ago that these were not perfect people any more
than we are.
Without known exception, every first-wave feminist who spoke out on abortion strongly
opposed it. Some addressed the unmet needs of women driven to abortion; others
focused on the children threatened by it; and all expressed intense and unwavering
opposition to it.
Feminists for Life surges forward to fulfill the urgent, unrealized dreams of first-wave
feminists Alice Paul, Susan B. Anthony, and others–to systematically eliminate
the root causes that drive women to abortion.
While we seek solutions in homes, the workplace, schools, and communities–especially
for those at highest risk of abortion–we stay true to our core feminist beliefs
of nonviolence, nondiscrimination, and justice for all.
Your support ensures that through our advocacy and education we can reach that once-far
shore [http://r20.rs6.net/tn.jsp?f=001uxXlJHz_agt_KyTK-ZG1iu-G7f1240JNO8aj9_qEy2NwxX3hF1qi1zQPT-qvbrIwDrf7Hi2n3rOV1gVFPwDiqGjbRRblGHAaH-K0LRwWButD0EtSWXL7p-X88FBt0kXoLE_rEy53cB8d3AQm7mE4QPxRTAuebsV3-iri01ZcmfwoaDc2bfZMJyTAV8M3iYLGZ5JWnKFhrnQ=&c=Ij8piOkwpRromd3428GvHs9zk-7aTLodOWuOO_kW7fO-De-dhX6Nog==&ch=aJOcbZpjQPemp-uZzWGoIGcx_SfGVrxzn3iUxB_DPmLDhAK8MyoMyA==].
That day, when no woman feels driven to abortion, is coming-propelled ever faster
by you.
That day is coming.
Because women deserve better,
Serrin M. Foster
President
PS. If you haven’t received the latest copy of The American Feminist®. with Serrin’s
intro (above), please contact member services to ensure your support is current
($35 or more annually/$25 for students.) Or join now at www.feministsforlife.org/support
[http://r20.rs6.net/tn.jsp?f=001uxXlJHz_agt_KyTK-ZG1iu-G7f1240JNO8aj9_qEy2NwxX3hF1qi12MtWekOu_Xia67NuXmKa6kAnz5-azJ9WoHk5b2v3MST6Mgtmu4Df4NHBL-9Q0gUVgH4FF0hyYUcSrzU27oBTX0MzHRJsmhRPHwMZ0ZwqKdXj6yzBa1yCs5PsiEImqfdfOSUAtiQlqAi&c=Ij8piOkwpRromd3428GvHs9zk-7aTLodOWuOO_kW7fO-De-dhX6Nog==&ch=aJOcbZpjQPemp-uZzWGoIGcx_SfGVrxzn3iUxB_DPmLDhAK8MyoMyA==]
to receive your FFL Welcome Kit.
Join us on Facebook (www.facebook.com/feministsforlife [http://r20.rs6.net/tn.jsp?f=001uxXlJHz_agt_KyTK-ZG1iu-G7f1240JNO8aj9_qEy2NwxX3hF1qi12hksWFUYzuAcEga9rwJ1Mwq6TuR_4oIv5vQgS8IUK376wYRwQ6vGAeMMYQQkalQZtCFR3Jds69LZ5B1yih6Vs6OyULYIb4u1vlQJgufbHjeQcN93qwIxNpus_JziFlv-lEntHwYdNdm&c=Ij8piOkwpRromd3428GvHs9zk-7aTLodOWuOO_kW7fO-De-dhX6Nog==&ch=aJOcbZpjQPemp-uZzWGoIGcx_SfGVrxzn3iUxB_DPmLDhAK8MyoMyA==])
as we discuss the suffragists featured in this issue. Thank you!
Women Deserve Better, The American Feminist, and Remarkable Pro-Life Women
are a registered trademarks of Feminists for Life of America.
Feminists for Life of America is a 501©3 nonprofit.
Membership contributions and donations are tax-deductible to the extent allowed
by law.
For more information, go to http://www.feministsforlife.org/support/ [http://r20.rs6.net/tn.jsp?f=001uxXlJHz_agt_KyTK-ZG1iu-G7f1240JNO8aj9_qEy2NwxX3hF1qi1zQPT-qvbrIwDrf7Hi2n3rOV1gVFPwDiqGjbRRblGHAaH-K0LRwWButD0EtSWXL7p-X88FBt0kXoLE_rEy53cB8d3AQm7mE4QPxRTAuebsV3-iri01ZcmfwoaDc2bfZMJyTAV8M3iYLGZ5JWnKFhrnQ=&c=Ij8piOkwpRromd3428GvHs9zk-7aTLodOWuOO_kW7fO-De-dhX6Nog==&ch=aJOcbZpjQPemp-uZzWGoIGcx_SfGVrxzn3iUxB_DPmLDhAK8MyoMyA==]
&
&
&
Forward this email
<EMAIL_ADDRESS>This email was sent to<EMAIL_ADDRESS>by<EMAIL_ADDRESS>Update Profile/Email Address
http://visitor.constantcontact.com/do?p=oo&m=001Q-HkL4DKCBRaE4RH1EOTXw%3D%3D&ch=5af11d60-4f61-11e3-9d28-d4ae5275dbea&ca=c360539c-46e0-4337-a52d-8cc8f06c10d6
Instant removal with SafeUnsubscribe™
http://visitor.constantcontact.com/do?p=un&m=001Q-HkL4DKCBRaE4RH1EOTXw%3D%3D&ch=5af11d60-4f61-11e3-9d28-d4ae5275dbea&ca=c360539c-46e0-4337-a52d-8cc8f06c10d6
Privacy Policy:
http://ui.constantcontact.com/roving/CCPrivacyPolicy.jsp
Online Marketing by
Constant Contact®
www.constantcontact.com
Feminists for Life | P.O. Box 320667 | Alexandria | VA | 22320


|
ML-Agents Toolkit
v0.4
|
Agent Monobehavior class that is attached to a Unity GameObject, making it an Agent. More...
Inherits MonoBehaviour.
Public Member Functions | |
| void | GiveBrain (Brain brain) |
| Updates the Brain for the agent. More... | |
| int | GetStepCount () |
| Returns the current step counter (within the current epside). More... | |
| void | ResetReward () |
| Resets the step reward and possibly the episode reward for the agent. More... | |
| void | SetReward (float reward) |
| Overrides the current step reward of the agent and updates the episode reward accordingly. More... | |
| void | AddReward (float increment) |
| Increments the step and episode rewards by the provided value. More... | |
| float | GetReward () |
| Retrieves the step reward for the Agent. More... | |
| float | GetCumulativeReward () |
| Retrieves the episode reward for the Agent. More... | |
| void | Done () |
| Sets the done flag to true. More... | |
| void | RequestDecision () |
| Is called when the agent must request the brain for a new decision. More... | |
| void | RequestAction () |
| Is called then the agent must perform a new action. More... | |
| bool | IsMaxStepReached () |
| Indicates if the agent has reached his maximum number of steps. More... | |
| bool | IsDone () |
| Indicates if the agent is done More... | |
| virtual void | InitializeAgent () |
| Initializes the agent, called once when the agent is enabled. More... | |
| virtual void | CollectObservations () |
| Collects the (vector, visual, text) observations of the agent. More... | |
| void | SetTextObs (string textObservation) |
| Sets the text observation. More... | |
| virtual void | AgentAction (float[] vectorAction, string textAction) |
| Specifies the agent behavior at every step based on the provided action. More... | |
| virtual void | AgentAction (float[] vectorAction, string textAction, CommunicatorObjects.CustomAction customAction) |
| Specifies the agent behavior at every step based on the provided action. More... | |
| virtual void | AgentOnDone () |
| Specifies the agent behavior when done and AgentParameters.resetOnDone is false. More... | |
| virtual void | AgentReset () |
| Specifies the agent behavior when being reset, which can be due to the agent or Academy being done (i.e. More... | |
| void | UpdateVectorAction (float[] vectorActions) |
| Updates the vector action. More... | |
| void | UpdateMemoriesAction (List< float > memories) |
| Updates the memories action. More... | |
| void | AppendMemoriesAction (List< float > memories) |
| void | UpdateTextAction (string textActions) |
| Updates the text action. More... | |
| void | UpdateCustomAction (CommunicatorObjects.CustomAction customAction) |
| Updates the custom action. More... | |
| void | UpdateValueAction (float value) |
| Updates the value of the agent. More... | |
| void | SetCustomObservation (CustomObservation customObservation) |
| Sets the custom observation for the agent for this episode. More... | |
Static Public Member Functions | |
| static void | ObservationToTexture (Camera obsCamera, int width, int height, ref Texture2D texture2D) |
| Converts a camera and correspinding resolution to a 2D texture. More... | |
| static void | ObservationToTexture (RenderTexture obsTexture, int width, int height, ref Texture2D texture2D) |
| Converts a RenderTexture and correspinding resolution to a 2D texture. More... | |
Public Attributes | |
| Brain | brain |
| The Brain attached to this agent. More... | |
| AgentParameters | agentParameters |
| Agent parameters specified within the Editor via AgentEditor. More... | |
Protected Member Functions | |
| void | SetActionMask (IEnumerable< int > actionIndices) |
| Sets an action mask for discrete control agents. More... | |
| void | SetActionMask (int actionIndex) |
| Sets an action mask for discrete control agents. More... | |
| void | SetActionMask (int branch, int actionIndex) |
| Sets an action mask for discrete control agents. More... | |
| void | SetActionMask (int branch, IEnumerable< int > actionIndices) |
| Modifies an action mask for discrete control agents. More... | |
| void | AddVectorObs (float observation) |
| Adds a float observation to the vector observations of the agent. More... | |
| void | AddVectorObs (int observation) |
| Adds an integer observation to the vector observations of the agent. More... | |
| void | AddVectorObs (Vector3 observation) |
| Adds an Vector3 observation to the vector observations of the agent. More... | |
| void | AddVectorObs (Vector2 observation) |
| Adds an Vector2 observation to the vector observations of the agent. More... | |
| void | AddVectorObs (IEnumerable< float > observation) |
| Adds a collection of float observations to the vector observations of the agent. More... | |
| void | AddVectorObs (Quaternion observation) |
| Adds a quaternion observation to the vector observations of the agent. More... | |
| void | AddVectorObs (bool observation) |
| Adds a boolean observation to the vector observation of the agent. More... | |
| void | AddVectorObs (int observation, int range) |
| float | GetValueEstimate () |
| float | ScaleAction (float rawAction, float min, float max) |
| Scales continous action from [-1, 1] to arbitrary range. More... | |
Agent Monobehavior class that is attached to a Unity GameObject, making it an Agent.
An agent produces observations and takes actions in the environment. Observations are determined by the cameras attached to the agent in addition to the vector observations implemented by the user in CollectObservations. On the other hand, actions are determined by decisions produced by a linked Brain. Currently, this class is expected to be extended to implement the desired agent behavior.
Simply speaking, an agent roams through an environment and at each step of the environment extracts its current observation, sends them to its linked brain and in return receives an action from its brain. In practice, however, an agent need not send its observation at every step since very little may have changed between sucessive steps. Currently, how often an agent updates its brain with a fresh observation is determined by the Academy.
At any step, an agent may be considered done. This could occur due to a variety of reasons:
Here, an agent reaches an end state if it completes its task successfully or somehow fails along the way. In the case where an agent is done before the academy, it either resets and restarts, or just lingers until the academy is done.
An important note regarding steps and episodes is due. Here, an agent step corresponds to an academy step, which also corresponds to Unity environment step (i.e. each FixedUpdate call). This is not the case for episodes. The academy controls the global episode count and each agent controls its own local episode count and can reset and start a new local episode independently (based on its own experience). Thus an academy (global) episode can be viewed as the upper-bound on an agents episode length and that within a single global episode, an agent may have completed multiple local episodes. Consequently, if an agent max step is set to a value larger than the academy max steps value, then the academy value takes precedence (since the agent max step will never be reached).
Lastly, note that at any step the brain linked to the agent is allowed to change programmatically with GiveBrain.
Implementation-wise, it is required that this class is extended and the virtual methods overridden. For sample implementations of agent behavior, see the Examples/ directory within this Unity project.
| void AddReward | ( | float | increment | ) |
Increments the step and episode rewards by the provided value.
| increment | Incremental reward value. |
|
protected |
Adds a boolean observation to the vector observation of the agent.
Increases the size of the agent's vector observation by 1.
| observation |
|
protected |
Adds a float observation to the vector observations of the agent.
Increases the size of the agents vector observation by 1.
| observation | Observation. |
|
protected |
Adds a collection of float observations to the vector observations of the agent.
Increases the size of the agents vector observation by size of the collection.
| observation | Observation. |
|
protected |
Adds an integer observation to the vector observations of the agent.
Increases the size of the agents vector observation by 1.
| observation | Observation. |
|
protected |
|
protected |
Adds a quaternion observation to the vector observations of the agent.
Increases the size of the agents vector observation by 4.
| observation | Observation. |
|
protected |
Adds an Vector2 observation to the vector observations of the agent.
Increases the size of the agents vector observation by 2.
| observation | Observation. |
|
protected |
Adds an Vector3 observation to the vector observations of the agent.
Increases the size of the agents vector observation by 3.
| observation | Observation. |
|
virtual |
Specifies the agent behavior at every step based on the provided action.
| vectorAction | Vector action. Note that for discrete actions, the provided array will be of length 1. |
| textAction | Text action. |
|
virtual |
Specifies the agent behavior at every step based on the provided action.
| vectorAction | Vector action. Note that for discrete actions, the provided array will be of length 1. |
| textAction | Text action. |
| customAction | A custom action, defined by the user as custom protobuffer message. Useful if the action is hard to encode as either a flat vector or a single string. |
|
virtual |
Specifies the agent behavior when done and AgentParameters.resetOnDone is false.
This method can be used to remove the agent from the scene.
|
virtual |
Specifies the agent behavior when being reset, which can be due to the agent or Academy being done (i.e.
completion of local or global episode).
| void AppendMemoriesAction | ( | List< float > | memories | ) |
|
virtual |
Collects the (vector, visual, text) observations of the agent.
The agent observation describes the current environment from the perspective of the agent.
Simply, an agents observation is any environment information that helps the Agent acheive its goal. For example, for a fighting Agent, its observation could include distances to friends or enemies, or the current level of ammunition at its disposal. Recall that an Agent may attach vector, visual or textual observations. Vector observations are added by calling the provided helper methods:
| void Done | ( | ) |
Sets the done flag to true.
| float GetCumulativeReward | ( | ) |
Retrieves the episode reward for the Agent.
| float GetReward | ( | ) |
Retrieves the step reward for the Agent.
| int GetStepCount | ( | ) |
Returns the current step counter (within the current epside).
|
protected |
| void GiveBrain | ( | Brain | brain | ) |
Updates the Brain for the agent.
Any brain currently assigned to the agent will be replaced with the provided one.
The agent unsubscribes from its current brain (if it has one) and subscribes to the provided brain. This enables contextual brains, that is, updating the behaviour (hence brain) of the agent depending on the context of the game. For example, we may utilize one (wandering) brain when an agent is randomly exploring an open world, but switch to another (fighting) brain when it comes into contact with an enemy.
| brain | New brain to subscribe this agent to |
|
virtual |
Initializes the agent, called once when the agent is enabled.
Can be left empty if there is no special, unique set-up behavior for the agent.
One sample use is to store local references to other objects in the scene which would facilitate computing this agents observation.
| bool IsDone | ( | ) |
Indicates if the agent is done
true
, if the agent is done, false
otherwise. | bool IsMaxStepReached | ( | ) |
Indicates if the agent has reached his maximum number of steps.
true
, if max step reached was reached, false
otherwise.
|
static |
Converts a camera and correspinding resolution to a 2D texture.
| obsCamera | Camera. |
| width | Width of resulting 2D texture. |
| height | Height of resulting 2D texture. |
| texture2D | Texture2D to render to. |
|
static |
Converts a RenderTexture and correspinding resolution to a 2D texture.
| obsTexture | RenderTexture. |
| width | Width of resulting 2D texture. |
| height | Height of resulting 2D texture. |
| texture2D | Texture2D to render to. |
| void RequestAction | ( | ) |
Is called then the agent must perform a new action.
| void RequestDecision | ( | ) |
Is called when the agent must request the brain for a new decision.
| void ResetReward | ( | ) |
Resets the step reward and possibly the episode reward for the agent.
|
protected |
Scales continous action from [-1, 1] to arbitrary range.
| rawAction | |
| min | |
| max |
|
protected |
Sets an action mask for discrete control agents.
When used, the agent will not be able to perform the action passed as argument at the next decision. If no branch is specified, the default branch will be 0. The actionIndex or actionIndices correspond to the action the agent will be unable to perform.
| actionIndices | The indices of the masked actions on branch 0 |
|
protected |
Sets an action mask for discrete control agents.
When used, the agent will not be able to perform the action passed as argument at the next decision. If no branch is specified, the default branch will be 0. The actionIndex or actionIndices correspond to the action the agent will be unable to perform.
| actionIndex | The index of the masked action on branch 0 |
|
protected |
Modifies an action mask for discrete control agents.
When used, the agent will not be able to perform the action passed as argument at the next decision. If no branch is specified, the default branch will be 0. The actionIndex or actionIndices correspond to the action the agent will be unable to perform.
| branch | The branch for which the actions will be masked |
| actionIndices | The indices of the masked actions |
|
protected |
Sets an action mask for discrete control agents.
When used, the agent will not be able to perform the action passed as argument at the next decision. If no branch is specified, the default branch will be 0. The actionIndex or actionIndices correspond to the action the agent will be unable to perform.
| branch | The branch for which the actions will be masked |
| actionIndex | The index of the masked action |
| void SetCustomObservation | ( | CustomObservation | customObservation | ) |
Sets the custom observation for the agent for this episode.
| customObservation | New value of the agent's custom observation. |
| void SetReward | ( | float | reward | ) |
Overrides the current step reward of the agent and updates the episode reward accordingly.
| reward | The new value of the reward. |
| void SetTextObs | ( | string | textObservation | ) |
Sets the text observation.
| textObservation | The text observation. |
| void UpdateCustomAction | ( | CommunicatorObjects.CustomAction | customAction | ) |
Updates the custom action.
| customAction | Custom action. |
| void UpdateMemoriesAction | ( | List< float > | memories | ) |
Updates the memories action.
| memories | Memories. |
| void UpdateTextAction | ( | string | textActions | ) |
Updates the text action.
| textActions | Text actions. |
| void UpdateValueAction | ( | float | value | ) |
Updates the value of the agent.
| textActions | Text actions. |
| void UpdateVectorAction | ( | float[] | vectorActions | ) |
Updates the vector action.
| vectorActions | Vector actions. |
| AgentParameters agentParameters |
Agent parameters specified within the Editor via AgentEditor.
| Brain brain |
The Brain attached to this agent.
A brain can be attached either directly from the Editor through AgentEditor or programmatically through GiveBrain. It is OK for an agent to not have a brain, as long as no decision is requested.